diff --git a/DEPS b/DEPS index 1f6b8306..6fd83f49 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '44e8cf87d2704443509ebb92d6e591b4f871c531', + 'v8_revision': 'a361a94a9378ce4b8b38304ae9dbf43de3a8dbcd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -56,7 +56,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. - 'buildtools_revision': 'b53a03df323e7fa7dafd892adbe70bf9f3cc97f7', + 'buildtools_revision': 'ee9c3a70889f452fb0cf10792ba3cb26de2d071e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other.
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn index e9b2f3af..ba86f9a 100644 --- a/android_webview/test/embedded_test_server/BUILD.gn +++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -15,10 +15,8 @@ deps = [ "//base:base_java", "//base:base_java_test_support", - "//net/android:embedded_test_server_aidl_java", "//net/android:net_java", "//net/android:net_java_test_support", - "//net/android:net_java_test_support_provider", ] }
diff --git a/base/process/kill.h b/base/process/kill.h index d12e800..68bce951 100644 --- a/base/process/kill.h +++ b/base/process/kill.h
@@ -132,7 +132,7 @@ // aggressive about ensuring that the process terminates. // // On Linux this method does not block the calling thread. -// On OS X this method may block for up to 2 seconds. +// On OS X and Fuchsia, this method may block for up to 2 seconds. // // NOTE: The process must have been opened with the PROCESS_TERMINATE and // SYNCHRONIZE permissions.
diff --git a/base/process/kill_fuchsia.cc b/base/process/kill_fuchsia.cc index c3490e20..273802c 100644 --- a/base/process/kill_fuchsia.cc +++ b/base/process/kill_fuchsia.cc
@@ -49,28 +49,17 @@ void EnsureProcessTerminated(Process process) { DCHECK(!process.is_current()); + // Wait for up to two seconds for the process to terminate, and then kill it + // forcefully if it hasn't already exited. mx_signals_t signals; - if (mx_object_wait_one(process.Handle(), MX_TASK_TERMINATED, 0, &signals) == - NO_ERROR) { + if (mx_object_wait_one(process.Handle(), MX_TASK_TERMINATED, + mx_deadline_after(MX_SEC(2)), &signals) == NO_ERROR) { DCHECK(signals & MX_TASK_TERMINATED); // If already signaled, then the process is terminated. return; } - PostDelayedTaskWithTraits( - FROM_HERE, - {TaskPriority::BACKGROUND, TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - Bind( - [](Process process) { - mx_signals_t signals; - if (mx_object_wait_one(process.Handle(), MX_TASK_TERMINATED, 0, - &signals) == NO_ERROR) { - return; - } - process.Terminate(1, false); - }, - Passed(&process)), - TimeDelta::FromSeconds(2)); + process.Terminate(/*exit_code=*/1, /*wait=*/false); } } // namespace base
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc index 8236ab8..6d1ebfd4 100644 --- a/base/process/process_util_unittest.cc +++ b/base/process/process_util_unittest.cc
@@ -64,6 +64,9 @@ #if defined(OS_ANDROID) #include "third_party/lss/linux_syscall_support.h" #endif +#if defined(OS_FUCHSIA) +#include <magenta/syscalls.h> +#endif using base::FilePath; @@ -869,11 +872,23 @@ // TODO(port): port those unit tests. bool IsProcessDead(base::ProcessHandle child) { +#if defined(OS_FUCHSIA) + // ProcessHandle is an mx_handle_t, not a pid on Fuchsia, so waitpid() doesn't + // make sense. + mx_signals_t signals; + // Timeout of 0 to check for termination, but non-blocking. + if (mx_object_wait_one(child, MX_TASK_TERMINATED, 0, &signals) == NO_ERROR) { + DCHECK(signals & MX_TASK_TERMINATED); + return true; + } + return false; +#else // waitpid() will actually reap the process which is exactly NOT what we // want to test for. The good thing is that if it can't find the process // we'll get a nice value for errno which we can test for. const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG)); return result == -1 && errno == ECHILD; +#endif } TEST_F(ProcessUtilTest, DelayedTermination) {
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index b2ab651..2e3d1b0 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -101,7 +101,7 @@ def BuildBootfs(output_directory, runtime_deps_path, test_name, gtest_filter, - gtest_repeat, dry_run): + gtest_repeat, test_launcher_filter_file, dry_run): with open(runtime_deps_path) as f: lines = f.readlines() @@ -133,6 +133,14 @@ autorun_file.write('#!/bin/sh\n') autorun_file.write('/system/' + os.path.basename(test_name)) autorun_file.write(' --test-launcher-retry-limit=0') + if test_launcher_filter_file: + test_launcher_filter_file = os.path.abspath(test_launcher_filter_file) + filter_file_on_device = MakeTargetImageName( + common_prefix, output_directory, test_launcher_filter_file) + autorun_file.write(' --test-launcher-filter-file=/system/' + + filter_file_on_device) + target_source_pairs.append( + [filter_file_on_device, test_launcher_filter_file]) if gtest_filter: autorun_file.write(' --gtest_filter=' + gtest_filter) if gtest_repeat: @@ -199,11 +207,13 @@ help='GTest filter to use in place of any default') parser.add_argument('--gtest_repeat', help='GTest repeat value to use') + parser.add_argument('--test-launcher-filter-file', + help='Pass filter file through to target process') args = parser.parse_args() bootfs = BuildBootfs(args.output_directory, args.runtime_deps_path, args.test_name, args.gtest_filter, args.gtest_repeat, - args.dry_run) + args.test_launcher_filter_file, args.dry_run) qemu_path = os.path.join(SDK_ROOT, 'qemu', 'bin', 'qemu-system-x86_64')
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 20cc2de..0e191073 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -339,8 +339,8 @@ to build with.""" env_version = GetVisualStudioVersion() if env_version == '2015': - # Update 3 final with patches with 10.0.14393.0 SDK. - return ['d3cb0e37bdd120ad0ac4650b674b09e81be45616'] + # Update 3 final with fixed 10.0.15063.0 SDK and patched event.h. + return ['a11b39300bafe01d9d46bbc16483e373503acc29'] if env_version == '2017': # VS 2017 Update 3 Preview 2 with 10.0.15063.0 SDK and patched event.h. return ['425bd64734a387734dfcf445b285a7c5073e4262']
diff --git a/chrome/VERSION b/chrome/VERSION index 5ec670d3..59a6461 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=61 MINOR=0 -BUILD=3132 +BUILD=3133 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 8c037d7..50855cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -364,7 +364,6 @@ if (wrapper == null) return null; ThreadUtils.assertOnUiThread(); sInstance = new VrShellDelegate(activity, wrapper); - return sInstance; } @@ -464,6 +463,7 @@ mPaused = ApplicationStatus.getStateForActivity(activity) != ActivityState.RESUMED; updateVrSupportLevel(); mNativeVrShellDelegate = nativeInit(); + createNonPresentingNativeContext(); mFeedbackFrequency = VrFeedbackStatus.getFeedbackFrequency(); mEnterVrHandler = new Handler(); Choreographer.getInstance().postFrameCallback(new FrameCallback() { @@ -523,9 +523,7 @@ mActivity = activity; mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(mActivity); if (mNativeVrShellDelegate == 0 || mNonPresentingGvrContext == null) return; - shutdownNonPresentingNativeContext(); - nativeUpdateNonPresentingContext( - mNativeVrShellDelegate, createNonPresentingNativeContext()); + resetNonPresentingNativeContext(); } /** @@ -536,6 +534,7 @@ private void updateVrSupportLevel() { if (mVrClassesWrapper == null) { mVrSupportLevel = VR_NOT_AVAILABLE; + shutdownNonPresentingNativeContext(); return; } if (mVrCoreVersionChecker == null) { @@ -544,8 +543,11 @@ if (mVrDaydreamApi == null) { mVrDaydreamApi = mVrClassesWrapper.createVrDaydreamApi(mActivity); } - mVrSupportLevel = getVrSupportLevel( + int supportLevel = getVrSupportLevel( mVrDaydreamApi, mVrCoreVersionChecker, mActivity.getActivityTab()); + if (supportLevel == mVrSupportLevel) return; + mVrSupportLevel = supportLevel; + resetNonPresentingNativeContext(); } /** @@ -640,6 +642,8 @@ mVrClassesWrapper.setVrModeEnabled(mActivity, true); mInVr = true; mShouldShowPageInfo = false; + shutdownNonPresentingNativeContext(); + // Lock orientation to landscape after enter VR. mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); @@ -807,6 +811,8 @@ private void onResume() { mPaused = false; + updateVrSupportLevel(); + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { if (mNativeVrShellDelegate != 0) nativeOnResume(mNativeVrShellDelegate); @@ -816,11 +822,14 @@ if (mVrSupportLevel != VR_DAYDREAM) return; if (isVrShellEnabled(mVrSupportLevel) && activitySupportsVrBrowsing(mActivity)) { - // registerDaydreamIntent is slow, so run it after resuming. + // Perform slow initialization asynchronously. new Handler().post(new Runnable() { @Override public void run() { - if (!mPaused) registerDaydreamIntent(mVrDaydreamApi, mActivity); + if (!mPaused) { + registerDaydreamIntent(mVrDaydreamApi, mActivity); + createNonPresentingNativeContext(); + } } }); } @@ -935,20 +944,27 @@ return mIsDaydreamCurrentViewer; } - @CalledByNative - private long createNonPresentingNativeContext() { - if (mVrClassesWrapper == null) return 0; - // Update VR support level as it can change at runtime - updateVrSupportLevel(); - if (mVrSupportLevel == VR_NOT_AVAILABLE) return 0; - mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrContext(mActivity); - if (mNonPresentingGvrContext == null) return 0; - return mNonPresentingGvrContext.getNativeGvrContext(); + private void resetNonPresentingNativeContext() { + shutdownNonPresentingNativeContext(); + createNonPresentingNativeContext(); } - @CalledByNative + private void createNonPresentingNativeContext() { + if (mNonPresentingGvrContext != null) return; + if (mVrClassesWrapper == null) return; + if (mVrSupportLevel == VR_NOT_AVAILABLE) return; + if (mNativeVrShellDelegate == 0) return; + mNonPresentingGvrContext = mVrClassesWrapper.createNonPresentingGvrContext(mActivity); + if (mNonPresentingGvrContext == null) return; + nativeUpdateNonPresentingContext( + mNativeVrShellDelegate, mNonPresentingGvrContext.getNativeGvrContext()); + } + private void shutdownNonPresentingNativeContext() { if (mNonPresentingGvrContext == null) return; + if (mNativeVrShellDelegate != 0) { + nativeUpdateNonPresentingContext(mNativeVrShellDelegate, 0); + } mNonPresentingGvrContext.shutdown(); mNonPresentingGvrContext = null; } @@ -989,6 +1005,7 @@ public void shutdownVr(boolean disableVrMode, boolean canReenter, boolean stayingInChrome) { cancelPendingVrEntry(); if (!mInVr) return; + if (mShowingDaydreamDoff) { onExitVrResult(true); return; @@ -1008,6 +1025,8 @@ if (disableVrMode) mVrClassesWrapper.setVrModeEnabled(mActivity, false); promptForFeedbackIfNeeded(stayingInChrome); + if (stayingInChrome) createNonPresentingNativeContext(); + // We don't want to show the PageInfo prompt if we return to Chrome // after shutting down for reasons other than a successful DOFF (e.g. // clicking the controller home button and returning to Chrome). @@ -1288,6 +1307,7 @@ shutdownVr(false /* disableVrMode */, false /* canReenter */, false /* stayingInChrome */); if (mNativeVrShellDelegate != 0) nativeDestroy(mNativeVrShellDelegate); mNativeVrShellDelegate = 0; + shutdownNonPresentingNativeContext(); ApplicationStatus.unregisterActivityStateListener(this); sInstance = null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java index 0b58ecc..4b328834 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/CompatibilityTextInputLayout.java
@@ -5,29 +5,21 @@ package org.chromium.chrome.browser.widget; import android.content.Context; -import android.os.Build; import android.support.design.widget.TextInputLayout; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; +import android.view.ViewGroup; import android.widget.EditText; import org.chromium.base.ApiCompatibilityUtils; -import javax.annotation.Nullable; +import java.util.ArrayList; /** - * Handles bugs with the Android Support library's {@link TextInputLayout} until Chrome can upgrade - * to a newer version. - * - * TODO(dfalcantara): Remove this super gross dirty hack once Chrome can roll version 24: - * https://crbug.com/603635 + * Wraps around the Android Support library's {@link TextInputLayout} to handle various issues. */ public class CompatibilityTextInputLayout extends TextInputLayout { - /** Whether or not the background has been mutated to work around the red line bug. */ - private boolean mIsBackgroundMutated; - public CompatibilityTextInputLayout(Context context) { super(context); } @@ -36,35 +28,32 @@ super(context, attrs); } - /** - * Super gross, dirty, awful hack for dealing with bugs in version 23 of the support library. - * - * Gleaned using dirty things from comments on the Android bug and support library source: - * https://code.google.com/p/android/issues/detail?id=190829 - */ - @Override - public void setError(@Nullable CharSequence error) { - if (!mIsBackgroundMutated && getEditText() != null && getEditText().getBackground() != null - && ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP))) { - getEditText().setBackground( - getEditText().getBackground().getConstantState().newDrawable()); - getEditText().getBackground().mutate(); - mIsBackgroundMutated = true; - } - - super.setError(error); - if (TextUtils.isEmpty(error)) setErrorEnabled(false); - } - @Override public void onFinishInflate() { super.onFinishInflate(); - if (getChildCount() == 1) { - // If there is a child to this TextInputLayout, automatically set the hint. - View child = getChildAt(0); - if (child instanceof EditText && child.getId() > NO_ID) { - ApiCompatibilityUtils.setLabelFor(this, child.getId()); + // If there is an EditText descendant, make this serve as the label for it. + ArrayList<EditText> views = new ArrayList<>(); + findEditTextChildren(this, views); + if (views.size() == 1) { + ApiCompatibilityUtils.setLabelFor(this, views.get(0).getId()); + } + } + + /** + * Dig through the descendant hierarchy to find the EditText displayed by this TextInputLayout. + * This is necessary because the Support Library version we're using automatically inserts a + * FrameLayout when a TextInputEditText isn't used as the child. + * + * @param views Finds all EditText children of the root view. + */ + private static void findEditTextChildren(ViewGroup root, ArrayList<EditText> views) { + for (int nChild = 0; nChild < root.getChildCount(); nChild++) { + View child = root.getChildAt(nChild); + if (child instanceof ViewGroup) { + findEditTextChildren((ViewGroup) child, views); + } else if (child instanceof EditText) { + views.add((EditText) child); } } }
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn index 239955b..532837a 100644 --- a/chrome/browser/android/vr_shell/BUILD.gn +++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -26,7 +26,6 @@ "font_fallback.h", "fps_meter.cc", "fps_meter.h", - "gl_browser_interface.h", "gltf_asset.cc", "gltf_asset.h", "gltf_parser.cc", @@ -122,10 +121,9 @@ "android_ui_gesture_target.h", "elbow_model.cc", "elbow_model.h", + "gl_browser_interface.h", "mailbox_to_surface_bridge.cc", "mailbox_to_surface_bridge.h", - "non_presenting_gvr_delegate.cc", - "non_presenting_gvr_delegate.h", "vr_compositor.cc", "vr_compositor.h", "vr_controller.cc",
diff --git a/chrome/browser/android/vr_shell/gl_browser_interface.h b/chrome/browser/android/vr_shell/gl_browser_interface.h index ae79529..cdc9bbd 100644 --- a/chrome/browser/android/vr_shell/gl_browser_interface.h +++ b/chrome/browser/android/vr_shell/gl_browser_interface.h
@@ -11,6 +11,7 @@ #include "chrome/browser/android/vr_shell/ui_interface.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "device/vr/vr_service.mojom.h" +#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" namespace blink { class WebInputEvent; @@ -25,7 +26,7 @@ virtual ~GlBrowserInterface() = default; virtual void ContentSurfaceChanged(jobject surface) = 0; - virtual void GvrDelegateReady() = 0; + virtual void GvrDelegateReady(gvr::ViewerType viewer_type) = 0; virtual void UpdateGamepadData(device::GvrGamepadData) = 0; virtual void AppButtonGesturePerformed(UiInterface::Direction direction) = 0; virtual void AppButtonClicked() = 0;
diff --git a/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.cc b/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.cc deleted file mode 100644 index 1f2518c..0000000 --- a/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.cc +++ /dev/null
@@ -1,169 +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. - -#include "chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h" - -#include <utility> - -#include "base/callback_helpers.h" -#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h" - -namespace vr_shell { - -NonPresentingGvrDelegate::NonPresentingGvrDelegate(gvr_context* context) - : task_runner_(base::ThreadTaskRunnerHandle::Get()), - binding_(this), - weak_ptr_factory_(this) { - // Context may be null, see VrShellDelegate#createNonPresentingNativeContext - // for possible reasons a context could fail to be created. For example, - // the user might uninstall apps or clear data after VR support was detected. - if (context) - gvr_api_ = gvr::GvrApi::WrapNonOwned(context); -} - -NonPresentingGvrDelegate::~NonPresentingGvrDelegate() { - StopVSyncLoop(); -} - -void NonPresentingGvrDelegate::OnVRVsyncProviderRequest( - device::mojom::VRVSyncProviderRequest request) { - binding_.Close(); - binding_.Bind(std::move(request)); - binding_.set_connection_error_handler( - base::Bind(&NonPresentingGvrDelegate::StopVSyncLoop, - weak_ptr_factory_.GetWeakPtr())); - StartVSyncLoop(); -} - -void NonPresentingGvrDelegate::Pause() { - vsync_task_.Cancel(); - vsync_paused_ = true; - if (gvr_api_) - gvr_api_->PauseTracking(); -} - -void NonPresentingGvrDelegate::Resume() { - if (!vsync_paused_) - return; - vsync_paused_ = false; - StartVSyncLoop(); -} - -device::mojom::VRVSyncProviderRequest -NonPresentingGvrDelegate::OnSwitchToPresentingDelegate() { - StopVSyncLoop(); - if (binding_.is_bound()) - return binding_.Unbind(); - return nullptr; -} - -void NonPresentingGvrDelegate::StopVSyncLoop() { - vsync_task_.Cancel(); - binding_.Close(); - if (!callback_.is_null()) { - base::ResetAndReturn(&callback_) - .Run(nullptr, base::TimeDelta(), -1, - device::mojom::VRVSyncProvider::Status::CLOSING); - } - if (gvr_api_) - gvr_api_->PauseTracking(); - // If the loop is stopped, it's not considered to be paused. - vsync_paused_ = false; -} - -void NonPresentingGvrDelegate::StartVSyncLoop() { - vsync_task_.Reset( - base::Bind(&NonPresentingGvrDelegate::OnVSync, base::Unretained(this))); - if (gvr_api_) { - gvr_api_->RefreshViewerProfile(); - gvr_api_->ResumeTracking(); - } - OnVSync(); -} - -void NonPresentingGvrDelegate::OnVSync() { - base::TimeTicks now = base::TimeTicks::Now(); - base::TimeTicks target; - - // Don't run the VSync loop if we're not bound. - if (!binding_.is_bound()) { - return; - } - - // Don't send VSyncs until we have a timebase/interval. - if (vsync_interval_.is_zero()) - return; - target = now + vsync_interval_; - int64_t intervals = (target - vsync_timebase_) / vsync_interval_; - target = vsync_timebase_ + intervals * vsync_interval_; - if (!vsync_task_.IsCancelled()) { - task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), - target - now); - } - - base::TimeDelta time = intervals * vsync_interval_; - if (!callback_.is_null()) { - SendVSync(time, base::ResetAndReturn(&callback_)); - } else { - pending_vsync_ = true; - pending_time_ = time; - } -} - -void NonPresentingGvrDelegate::GetVSync(GetVSyncCallback callback) { - if (!pending_vsync_) { - if (!callback_.is_null()) { - mojo::ReportBadMessage( - "Requested VSync before waiting for response to previous request."); - binding_.Close(); - return; - } - callback_ = std::move(callback); - return; - } - pending_vsync_ = false; - SendVSync(pending_time_, std::move(callback)); -} - -void NonPresentingGvrDelegate::UpdateVSyncInterval(int64_t timebase_nanos, - double interval_seconds) { - vsync_timebase_ = base::TimeTicks(); - vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); - vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); - StartVSyncLoop(); -} - -void NonPresentingGvrDelegate::SendVSync(base::TimeDelta time, - GetVSyncCallback callback) { - if (!gvr_api_) { - std::move(callback).Run(device::mojom::VRPosePtr(nullptr), time, -1, - device::mojom::VRVSyncProvider::Status::SUCCESS); - return; - } - - std::move(callback).Run( - GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), nullptr), time, -1, - device::mojom::VRVSyncProvider::Status::SUCCESS); -} - -void NonPresentingGvrDelegate::CreateVRDisplayInfo( - const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, - uint32_t device_id) { - if (!gvr_api_) { - callback.Run(device::mojom::VRDisplayInfoPtr(nullptr)); - return; - } - - gfx::Size webvr_size = GvrDelegate::GetRecommendedWebVrSize(gvr_api_.get()); - DVLOG(1) << __FUNCTION__ << ": resize recommended to " << webvr_size.width() - << "x" << webvr_size.height(); - callback.Run( - GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), webvr_size, device_id)); -} - -void NonPresentingGvrDelegate::UpdateContext(gvr_context* context) { - gvr_api_ = gvr::GvrApi::WrapNonOwned(context); -} - -} // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h b/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h deleted file mode 100644 index 24365a8..0000000 --- a/chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h +++ /dev/null
@@ -1,80 +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. - -#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_NON_PRESENTING_GVR_DELEGATE_H_ -#define CHROME_BROWSER_ANDROID_VR_SHELL_NON_PRESENTING_GVR_DELEGATE_H_ - -#include <jni.h> - -#include <memory> - -#include "base/cancelable_callback.h" -#include "base/macros.h" -#include "device/vr/android/gvr/gvr_delegate.h" -#include "device/vr/vr_service.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" - -namespace vr_shell { - -// A non presenting delegate for magic window mode. -class NonPresentingGvrDelegate : public device::GvrDelegate, - public device::mojom::VRVSyncProvider { - public: - explicit NonPresentingGvrDelegate(gvr_context* context); - - ~NonPresentingGvrDelegate() override; - - // GvrDelegate implementation - void SetWebVRSecureOrigin(bool secure_origin) override {} - void SubmitWebVRFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override {} - void UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size) override {} - void OnVRVsyncProviderRequest( - device::mojom::VRVSyncProviderRequest request) override; - void UpdateVSyncInterval(int64_t timebase_nanos, - double interval_seconds) override; - - void CreateVRDisplayInfo( - const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, - uint32_t device_id) override; - - void Pause(); - void Resume(); - device::mojom::VRVSyncProviderRequest OnSwitchToPresentingDelegate(); - - void UpdateContext(gvr_context* context); - - private: - void StopVSyncLoop(); - void StartVSyncLoop(); - void OnVSync(); - void SendVSync(base::TimeDelta time, GetVSyncCallback callback); - - // VRVSyncProvider implementation - void GetVSync(GetVSyncCallback callback) override; - - std::unique_ptr<gvr::GvrApi> gvr_api_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - base::CancelableClosure vsync_task_; - base::TimeTicks vsync_timebase_; - base::TimeDelta vsync_interval_; - - // Whether the vsync loop is paused, but not stopped. - bool vsync_paused_ = false; - base::TimeDelta pending_time_; - bool pending_vsync_ = false; - GetVSyncCallback callback_; - mojo::Binding<device::mojom::VRVSyncProvider> binding_; - base::WeakPtrFactory<NonPresentingGvrDelegate> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(NonPresentingGvrDelegate); -}; - -} // namespace vr_shell - -#endif // CHROME_BROWSER_ANDROID_VR_SHELL_NON_PRESENTING_GVR_DELEGATE_H_
diff --git a/chrome/browser/android/vr_shell/ui_elements/ui_element.cc b/chrome/browser/android/vr_shell/ui_elements/ui_element.cc index f45f82b..3183a159 100644 --- a/chrome/browser/android/vr_shell/ui_elements/ui_element.cc +++ b/chrome/browser/android/vr_shell/ui_elements/ui_element.cc
@@ -31,40 +31,9 @@ } // namespace -Transform::Transform() { - MakeIdentity(); -} - -Transform::Transform(const Transform& other) { - to_world = other.to_world; -} - -void Transform::MakeIdentity() { - to_world.MakeIdentity(); -} - -void Transform::Rotate(const gfx::Quaternion& q) { - // TODO(klausw): use specialized rotation code? Constructing the matrix - // via axis-angle quaternion is inefficient. - to_world.ConcatTransform(gfx::Transform(q)); -} - -void Transform::Translate(const gfx::Vector3dF& translation) { - to_world.matrix().postTranslate(translation.x(), translation.y(), - translation.z()); -} - -void Transform::Scale(const gfx::Vector3dF& scale) { - to_world.matrix().postScale(scale.x(), scale.y(), scale.z()); -} - -const gfx::Transform& WorldRectangle::TransformMatrix() const { - return transform_.to_world; -} - gfx::Point3F WorldRectangle::GetCenter() const { gfx::Point3F center; - transform_.to_world.TransformPoint(¢er); + transform_.TransformPoint(¢er); return center; } @@ -74,9 +43,9 @@ gfx::Point3F origin(0, 0, 0); gfx::Vector3dF x_axis(1, 0, 0); gfx::Vector3dF y_axis(0, 1, 0); - transform_.to_world.TransformPoint(&origin); - transform_.to_world.TransformVector(&x_axis); - transform_.to_world.TransformVector(&y_axis); + transform_.TransformPoint(&origin); + transform_.TransformVector(&x_axis); + transform_.TransformVector(&y_axis); gfx::Vector3dF origin_to_world = world_point - origin; float x = gfx::DotProduct(origin_to_world, x_axis) / gfx::DotProduct(x_axis, x_axis); @@ -88,8 +57,8 @@ gfx::Vector3dF WorldRectangle::GetNormal() const { gfx::Vector3dF x_axis(1, 0, 0); gfx::Vector3dF y_axis(0, 1, 0); - transform_.to_world.TransformVector(&x_axis); - transform_.to_world.TransformVector(&y_axis); + transform_.TransformVector(&x_axis); + transform_.TransformVector(&y_axis); gfx::Vector3dF normal = CrossProduct(y_axis, x_axis); normal.GetNormalized(&normal); return normal;
diff --git a/chrome/browser/android/vr_shell/ui_elements/ui_element.h b/chrome/browser/android/vr_shell/ui_elements/ui_element.h index e4e0942b..a45bed6 100644 --- a/chrome/browser/android/vr_shell/ui_elements/ui_element.h +++ b/chrome/browser/android/vr_shell/ui_elements/ui_element.h
@@ -54,23 +54,12 @@ SELF = 4, }; -// TODO(vollick): use gfx::Transform crbug.com/718004 -struct Transform { - Transform(); - explicit Transform(const Transform& other); - - void MakeIdentity(); - void Rotate(const gfx::Quaternion& quat); - void Translate(const gfx::Vector3dF& translation); - void Scale(const gfx::Vector3dF& scale); - - gfx::Transform to_world; -}; - class WorldRectangle { public: - const gfx::Transform& TransformMatrix() const; - Transform* mutable_transform() { return &transform_; } + const gfx::Transform& transform() const { return transform_; } + void set_transform(const gfx::Transform& transform) { + transform_ = transform; + } gfx::Point3F GetCenter() const; gfx::Vector3dF GetNormal() const; @@ -91,7 +80,7 @@ const gfx::Point3F& world_point) const; private: - Transform transform_; + gfx::Transform transform_; }; class UiElement : public WorldRectangle { @@ -227,13 +216,10 @@ void set_draw_phase(int draw_phase) { draw_phase_ = draw_phase; } // This transform can be used by children to derive position of its parent. - vr_shell::Transform& inheritable_transform() { + const gfx::Transform& inheritable_transform() const { return inheritable_transform_; } - const vr_shell::Transform& inheritable_transform() const { - return inheritable_transform_; - } - void set_inheritable_transform(const vr_shell::Transform& transform) { + void set_inheritable_transform(const gfx::Transform& transform) { inheritable_transform_ = transform; } @@ -319,7 +305,7 @@ int draw_phase_ = 1; // This transform can be used by children to derive position of its parent. - vr_shell::Transform inheritable_transform_; + gfx::Transform inheritable_transform_; // A flag usable during transformation calculates to avoid duplicate work. bool dirty_ = false; @@ -327,7 +313,7 @@ // An identifier used for testing and debugging, in lieu of a string. UiElementDebugId debug_id_ = UiElementDebugId::kNone; - vr_shell::Transform transform_; + gfx::Transform transform_; ColorScheme::Mode mode_ = ColorScheme::kModeNormal;
diff --git a/chrome/browser/android/vr_shell/ui_scene.cc b/chrome/browser/android/vr_shell/ui_scene.cc index a1b7574..1df212c 100644 --- a/chrome/browser/android/vr_shell/ui_scene.cc +++ b/chrome/browser/android/vr_shell/ui_scene.cc
@@ -21,7 +21,7 @@ void ApplyAnchoring(const UiElement& parent, XAnchoring x_anchoring, YAnchoring y_anchoring, - Transform* transform) { + gfx::Transform* transform) { // To anchor a child, use the parent's size to find its edge. float x_offset; switch (x_anchoring) { @@ -47,7 +47,7 @@ y_offset = 0.0f; break; } - transform->Translate(gfx::Vector3dF(x_offset, y_offset, 0)); + transform->matrix().postTranslate(x_offset, y_offset, 0); } } // namespace @@ -233,32 +233,36 @@ CHECK(parent != nullptr); } - Transform* transform = element->mutable_transform(); - transform->MakeIdentity(); - transform->Scale(element->size()); + gfx::Transform transform; + transform.Scale3d(element->size().x(), element->size().y(), + element->size().z()); element->set_computed_opacity(element->opacity()); element->set_computed_lock_to_fov(element->lock_to_fov()); // Compute an inheritable transformation that can be applied to this element, // and it's children, if applicable. - Transform* inheritable = &element->inheritable_transform(); - inheritable->MakeIdentity(); - inheritable->Scale(element->scale()); - inheritable->Rotate(element->rotation()); - inheritable->Translate(element->translation()); + gfx::Transform inheritable; + inheritable.matrix().postScale(element->scale().x(), element->scale().y(), + element->scale().z()); + inheritable.ConcatTransform(gfx::Transform(element->rotation())); + inheritable.matrix().postTranslate(element->translation().x(), + element->translation().y(), + element->translation().z()); if (parent) { ApplyAnchoring(*parent, element->x_anchoring(), element->y_anchoring(), - inheritable); + &inheritable); ApplyRecursiveTransforms(parent); - inheritable->to_world.ConcatTransform( - parent->inheritable_transform().to_world); + inheritable.ConcatTransform(parent->inheritable_transform()); element->set_computed_opacity(element->computed_opacity() * parent->opacity()); element->set_computed_lock_to_fov(parent->lock_to_fov()); } - transform->to_world.ConcatTransform(inheritable->to_world); + transform.ConcatTransform(inheritable); + + element->set_transform(transform); + element->set_inheritable_transform(inheritable); element->set_dirty(false); }
diff --git a/chrome/browser/android/vr_shell/ui_scene_unittest.cc b/chrome/browser/android/vr_shell/ui_scene_unittest.cc index b806a76..fe09178 100644 --- a/chrome/browser/android/vr_shell/ui_scene_unittest.cc +++ b/chrome/browser/android/vr_shell/ui_scene_unittest.cc
@@ -135,8 +135,8 @@ gfx::Point3F point(1, 0, 0); scene.OnBeginFrame(usToTicks(0)); - child->TransformMatrix().TransformPoint(&origin); - child->TransformMatrix().TransformPoint(&point); + child->transform().TransformPoint(&origin); + child->transform().TransformPoint(&point); EXPECT_VEC3F_NEAR(gfx::Point3F(6, 10, 0), origin); EXPECT_VEC3F_NEAR(gfx::Point3F(0, 10, 0), point); }
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc index 7558bf6..bee6100 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.cc +++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -57,9 +57,10 @@ base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_, surface)); } -void VrGLThread::GvrDelegateReady() { +void VrGLThread::GvrDelegateReady(gvr::ViewerType viewer_type) { main_thread_task_runner_->PostTask( - FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); + FROM_HERE, + base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_, viewer_type)); } void VrGLThread::UpdateGamepadData(device::GvrGamepadData pad) {
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h index c7709a04..dfecae5 100644 --- a/chrome/browser/android/vr_shell/vr_gl_thread.h +++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -48,7 +48,7 @@ // GlBrowserInterface implementation (VrShellGl calling to VrShell). void ContentSurfaceChanged(jobject surface) override; - void GvrDelegateReady() override; + void GvrDelegateReady(gvr::ViewerType viewer_type) override; void UpdateGamepadData(device::GvrGamepadData) override; void AppButtonClicked() override; void AppButtonGesturePerformed(UiInterface::Direction direction) override;
diff --git a/chrome/browser/android/vr_shell/vr_metrics_util.cc b/chrome/browser/android/vr_shell/vr_metrics_util.cc index 5ec7c9b..c4eff17 100644 --- a/chrome/browser/android/vr_shell/vr_metrics_util.cc +++ b/chrome/browser/android/vr_shell/vr_metrics_util.cc
@@ -16,7 +16,7 @@ bool VrMetricsUtil::has_logged_vr_runtime_version_ = false; void VrMetricsUtil::LogGvrVersionForVrViewerType( - gvr_context* context, + gvr::ViewerType viewer_type, const VrCoreInfo& vr_core_info) { if (has_logged_vr_runtime_version_) { return; @@ -46,9 +46,7 @@ break; } - ViewerType vr_viewer_type = - context ? GetVrViewerType(context) : ViewerType::UNKNOWN_TYPE; - switch (vr_viewer_type) { + switch (GetVrViewerType(viewer_type)) { case ViewerType::CARDBOARD: UMA_HISTOGRAM_SPARSE_SLOWLY("VRRuntimeVersion.GVR.Cardboard", encoded_version); @@ -66,15 +64,14 @@ has_logged_vr_runtime_version_ = true; } -void VrMetricsUtil::LogVrViewerType(gvr_context* context) { +void VrMetricsUtil::LogVrViewerType(gvr::ViewerType viewer_type) { UMA_HISTOGRAM_ENUMERATION("VRViewerType", - static_cast<int>(GetVrViewerType(context)), + static_cast<int>(GetVrViewerType(viewer_type)), static_cast<int>(ViewerType::VIEWER_TYPE_MAX)); } -ViewerType VrMetricsUtil::GetVrViewerType(gvr_context* context) { - auto gvr_api = gvr::GvrApi::WrapNonOwned(context); - switch (gvr_api->GetViewerType()) { +ViewerType VrMetricsUtil::GetVrViewerType(gvr::ViewerType viewer_type) { + switch (viewer_type) { case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM: return ViewerType::DAYDREAM; case gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD:
diff --git a/chrome/browser/android/vr_shell/vr_metrics_util.h b/chrome/browser/android/vr_shell/vr_metrics_util.h index 3075b91..7e73d84b 100644 --- a/chrome/browser/android/vr_shell/vr_metrics_util.h +++ b/chrome/browser/android/vr_shell/vr_metrics_util.h
@@ -8,7 +8,6 @@ #include "base/macros.h" #include "chrome/browser/android/vr_shell/vr_core_info.h" -#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" namespace vr_shell { @@ -22,12 +21,12 @@ class VrMetricsUtil { public: - static void LogGvrVersionForVrViewerType(gvr_context* context, + static void LogGvrVersionForVrViewerType(gvr::ViewerType viewer_type, const VrCoreInfo& vr_core_info); - static void LogVrViewerType(gvr_context* context); + static void LogVrViewerType(gvr::ViewerType viewer_type); private: - static ViewerType GetVrViewerType(gvr_context* context); + static ViewerType GetVrViewerType(gvr::ViewerType viewer_type); static bool has_logged_vr_runtime_version_;
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 1457dee..61ef878 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -105,7 +105,6 @@ delegate_provider_(delegate), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), reprojected_rendering_(reprojected_rendering), - gvr_api_(gvr_api), weak_ptr_factory_(this) { DVLOG(1) << __FUNCTION__ << "=" << this; DCHECK(g_instance == nullptr); @@ -404,25 +403,6 @@ ui_->SetWebVrSecureOrigin(secure_origin); } -void VrShell::SubmitWebVRFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) { - TRACE_EVENT1("gpu", "SubmitWebVRFrame", "frame", frame_index); - WaitForGlThread(); - PostToGlThread(FROM_HERE, - base::Bind(&VrShellGl::SubmitWebVRFrame, - gl_thread_->GetVrShellGl(), frame_index, mailbox)); -} - -void VrShell::UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size) { - WaitForGlThread(); - PostToGlThread(FROM_HERE, base::Bind(&VrShellGl::UpdateWebVRTextureBounds, - gl_thread_->GetVrShellGl(), frame_index, - left_bounds, right_bounds, source_size)); -} - void VrShell::CreateVRDisplayInfo( const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, uint32_t device_id) { @@ -432,13 +412,15 @@ gl_thread_->GetVrShellGl(), callback, device_id)); } -void VrShell::SetSubmitClient( - device::mojom::VRSubmitFrameClientPtr submit_client) { +void VrShell::ConnectPresentingService( + device::mojom::VRSubmitFrameClientPtr submit_client, + device::mojom::VRPresentationProviderRequest request) { WaitForGlThread(); - PostToGlThread( - FROM_HERE, - base::Bind(&VrShellGl::SetSubmitClient, gl_thread_->GetVrShellGl(), - base::Passed(submit_client.PassInterface()))); + PostToGlThread(FROM_HERE, + base::Bind(&VrShellGl::ConnectPresentingService, + gl_thread_->GetVrShellGl(), + base::Passed(submit_client.PassInterface()), + base::Passed(&request))); } base::android::ScopedJavaGlobalRef<jobject> VrShell::TakeContentSurface( @@ -479,8 +461,8 @@ compositor_->SurfaceChanged(content_surface_); } -void VrShell::GvrDelegateReady() { - delegate_provider_->SetPresentingDelegate(this, gvr_api_); +void VrShell::GvrDelegateReady(gvr::ViewerType viewer_type) { + delegate_provider_->SetDelegate(this, viewer_type); } void VrShell::OnPhysicalBackingSizeChanged( @@ -604,14 +586,6 @@ UiUnsupportedMode::kCount); } -void VrShell::OnVRVsyncProviderRequest( - device::mojom::VRVSyncProviderRequest request) { - WaitForGlThread(); - PostToGlThread(FROM_HERE, - base::Bind(&VrShellGl::OnRequest, gl_thread_->GetVrShellGl(), - base::Passed(&request))); -} - void VrShell::UpdateVSyncInterval(int64_t timebase_nanos, double interval_seconds) { PollMediaAccessFlag();
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index f4c2b18f..2453c45 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -22,7 +22,6 @@ #include "device/vr/android/gvr/gvr_delegate.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "device/vr/vr_service.mojom.h" -#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" namespace blink { @@ -33,10 +32,6 @@ class WebContents; } -namespace gpu { -struct MailboxHolder; -} - namespace ui { class WindowAndroid; } @@ -65,7 +60,7 @@ // The native instance of the Java VrShell. This class is not threadsafe and // must only be used on the UI thread. -class VrShell : public device::PresentingGvrDelegate, +class VrShell : public device::GvrDelegate, device::GvrGamepadDataProvider, device::CardboardGamepadDataProvider { public: @@ -138,7 +133,7 @@ void ContentWasShown(); void ContentSurfaceChanged(jobject surface); - void GvrDelegateReady(); + void GvrDelegateReady(gvr::ViewerType viewer_type); void OnPhysicalBackingSizeChanged( JNIEnv* env, @@ -186,23 +181,14 @@ // device::GvrDelegate implementation. void SetWebVRSecureOrigin(bool secure_origin) override; - void SubmitWebVRFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override; - void UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size) override; - void OnVRVsyncProviderRequest( - device::mojom::VRVSyncProviderRequest request) override; void UpdateVSyncInterval(int64_t timebase_nanos, double interval_seconds) override; void CreateVRDisplayInfo( const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, uint32_t device_id) override; - - // device::PresentingGvrDelegate implementation. - void SetSubmitClient( - device::mojom::VRSubmitFrameClientPtr submit_client) override; + void ConnectPresentingService( + device::mojom::VRSubmitFrameClientPtr submit_client, + device::mojom::VRPresentationProviderRequest request) override; void ProcessTabArray(JNIEnv* env, jobjectArray tabs, bool incognito); @@ -242,10 +228,6 @@ bool is_capturing_video_ = false; bool is_capturing_screen_ = false; - // TODO(mthiesse): Remove the need for this to be stored here. - // crbug.com/674594 - gvr_context* gvr_api_; - // Are we currently providing a gamepad factory to the gamepad manager? bool gvr_gamepad_source_active_ = false; bool cardboard_gamepad_source_active_ = false;
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.cc b/chrome/browser/android/vr_shell/vr_shell_delegate.cc index 733f906..0ed5550 100644 --- a/chrome/browser/android/vr_shell/vr_shell_delegate.cc +++ b/chrome/browser/android/vr_shell/vr_shell_delegate.cc
@@ -8,12 +8,12 @@ #include "base/android/jni_android.h" #include "base/callback_helpers.h" -#include "chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h" #include "chrome/browser/android/vr_shell/vr_metrics_util.h" #include "device/vr/android/gvr/gvr_delegate.h" #include "device/vr/android/gvr/gvr_device.h" #include "device/vr/android/gvr/gvr_device_provider.h" #include "jni/VrShellDelegate_jni.h" +#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h" using base::android::JavaParamRef; using base::android::AttachCurrentThread; @@ -31,7 +31,6 @@ DVLOG(1) << __FUNCTION__ << "=" << this; if (device_provider_) { device_provider_->Device()->OnExitPresent(); - device_provider_->Device()->OnDelegateChanged(); } if (!present_callback_.is_null()) { base::ResetAndReturn(&present_callback_).Run(false); @@ -52,38 +51,29 @@ Java_VrShellDelegate_getNativePointer(env, jdelegate)); } -void VrShellDelegate::SetPresentingDelegate( - device::PresentingGvrDelegate* delegate, - gvr_context* context) { - presenting_delegate_ = delegate; - // Clean up the non-presenting delegate. - JNIEnv* env = AttachCurrentThread(); - if (presenting_delegate_ && non_presenting_delegate_) { - non_presenting_delegate_ = nullptr; - Java_VrShellDelegate_shutdownNonPresentingNativeContext( - env, j_vr_shell_delegate_.obj()); - } +void VrShellDelegate::SetDelegate(device::GvrDelegate* delegate, + gvr::ViewerType viewer_type) { + gvr_delegate_ = delegate; if (device_provider_) { - device::GvrDevice* device = device_provider_->Device(); - device->OnDelegateChanged(); + device_provider_->Device()->OnDelegateChanged(); } - presenting_delegate_->UpdateVSyncInterval(timebase_nanos_, interval_seconds_); + gvr_delegate_->UpdateVSyncInterval(timebase_nanos_, interval_seconds_); if (pending_successful_present_request_) { - presenting_delegate_->SetSubmitClient(std::move(submit_client_)); + gvr_delegate_->ConnectPresentingService( + std::move(submit_client_), std::move(presentation_provider_request_)); base::ResetAndReturn(&present_callback_).Run(true); pending_successful_present_request_ = false; } - + JNIEnv* env = AttachCurrentThread(); std::unique_ptr<VrCoreInfo> vr_core_info = MakeVrCoreInfo(env); - VrMetricsUtil::LogGvrVersionForVrViewerType(context, *vr_core_info); + VrMetricsUtil::LogGvrVersionForVrViewerType(viewer_type, *vr_core_info); } void VrShellDelegate::RemoveDelegate() { - presenting_delegate_ = nullptr; + gvr_delegate_ = nullptr; if (device_provider_) { - CreateNonPresentingDelegate(); device_provider_->Device()->OnExitPresent(); device_provider_->Device()->OnDelegateChanged(); } @@ -93,7 +83,7 @@ const JavaParamRef<jobject>& obj, jboolean success) { CHECK(!present_callback_.is_null()); - if (success && !presenting_delegate_) { + if (success && !gvr_delegate_) { // We have to wait until the GL thread is ready since we have to pass it // the VRSubmitFrameClient. pending_successful_present_request_ = true; @@ -101,7 +91,8 @@ } if (success) { - presenting_delegate_->SetSubmitClient(std::move(submit_client_)); + gvr_delegate_->ConnectPresentingService( + std::move(submit_client_), std::move(presentation_provider_request_)); } base::ResetAndReturn(&present_callback_).Run(success); @@ -124,25 +115,20 @@ jdouble interval_seconds) { timebase_nanos_ = timebase_nanos; interval_seconds_ = interval_seconds; - if (presenting_delegate_) { - presenting_delegate_->UpdateVSyncInterval(timebase_nanos_, - interval_seconds_); - } - if (non_presenting_delegate_) { - non_presenting_delegate_->UpdateVSyncInterval(timebase_nanos_, - interval_seconds_); + if (gvr_delegate_) { + gvr_delegate_->UpdateVSyncInterval(timebase_nanos_, interval_seconds_); } } void VrShellDelegate::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { - if (non_presenting_delegate_) { - non_presenting_delegate_->Pause(); + if (gvr_api_) { + gvr_api_->PauseTracking(); } } void VrShellDelegate::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { - if (non_presenting_delegate_) { - non_presenting_delegate_->Resume(); + if (gvr_api_) { + gvr_api_->ResumeTracking(); } } @@ -150,8 +136,11 @@ JNIEnv* env, const JavaParamRef<jobject>& obj, jlong context) { - gvr_context* ctx = reinterpret_cast<gvr_context*>(context); - non_presenting_delegate_->UpdateContext(ctx); + if (context == 0) { + gvr_api_ = nullptr; + return; + } + gvr_api_ = gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(context)); } void VrShellDelegate::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { @@ -166,22 +155,15 @@ ClearDeviceProvider(); CHECK(!device_provider_); device_provider_ = device_provider; - if (!presenting_delegate_) { - CreateNonPresentingDelegate(); - } - device_provider_->Device()->OnDelegateChanged(); } void VrShellDelegate::ClearDeviceProvider() { - non_presenting_delegate_ = nullptr; - JNIEnv* env = AttachCurrentThread(); - Java_VrShellDelegate_shutdownNonPresentingNativeContext( - env, j_vr_shell_delegate_.obj()); device_provider_ = nullptr; } void VrShellDelegate::RequestWebVRPresent( device::mojom::VRSubmitFrameClientPtr submit_client, + device::mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) { if (!present_callback_.is_null()) { // Can only handle one request at a time. This is also extremely unlikely to @@ -192,6 +174,7 @@ present_callback_ = std::move(callback); submit_client_ = std::move(submit_client); + presentation_provider_request_ = std::move(request); // If/When VRShell is ready for use it will call SetPresentResult. JNIEnv* env = AttachCurrentThread(); @@ -214,19 +197,6 @@ Java_VrShellDelegate_getVrCoreInfo(env, j_vr_shell_delegate_.obj()))); } -void VrShellDelegate::CreateNonPresentingDelegate() { - JNIEnv* env = AttachCurrentThread(); - gvr_context* context = reinterpret_cast<gvr_context*>( - Java_VrShellDelegate_createNonPresentingNativeContext( - env, j_vr_shell_delegate_.obj())); - non_presenting_delegate_ = - base::MakeUnique<NonPresentingGvrDelegate>(context); - non_presenting_delegate_->UpdateVSyncInterval(timebase_nanos_, - interval_seconds_); - std::unique_ptr<VrCoreInfo> vr_core_info = MakeVrCoreInfo(env); - VrMetricsUtil::LogGvrVersionForVrViewerType(context, *vr_core_info); -} - void VrShellDelegate::OnActivateDisplayHandled(bool will_not_present) { if (will_not_present) { // WebVR page didn't request presentation in the vrdisplayactivate handler. @@ -236,9 +206,7 @@ } device::GvrDelegate* VrShellDelegate::GetDelegate() { - if (presenting_delegate_) - return presenting_delegate_; - return non_presenting_delegate_.get(); + return gvr_delegate_; } void VrShellDelegate::SetListeningForActivate(bool listening) { @@ -247,6 +215,28 @@ env, j_vr_shell_delegate_.obj(), listening); } +void VrShellDelegate::GetNextMagicWindowPose( + device::mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) { + if (!gvr_api_) { + std::move(callback).Run(nullptr); + return; + } + std::move(callback).Run( + device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), nullptr)); +} + +void VrShellDelegate::CreateVRDisplayInfo( + const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, + uint32_t device_id) { + if (gvr_delegate_) { + gvr_delegate_->CreateVRDisplayInfo(callback, device_id); + return; + } + // This is for magic window mode, which doesn't care what the render size is. + callback.Run(device::GvrDelegate::CreateDefaultVRDisplayInfo(gvr_api_.get(), + device_id)); +} + // ---------------------------------------------------------------------------- // Native JNI methods // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.h b/chrome/browser/android/vr_shell/vr_shell_delegate.h index 8265e347..013e8e4 100644 --- a/chrome/browser/android/vr_shell/vr_shell_delegate.h +++ b/chrome/browser/android/vr_shell/vr_shell_delegate.h
@@ -15,18 +15,16 @@ #include "chrome/browser/android/vr_shell/vr_core_info.h" #include "chrome/browser/android/vr_shell/vr_usage_monitor.h" #include "device/vr/android/gvr/gvr_delegate_provider.h" +#include "device/vr/vr_service.mojom.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" namespace device { class GvrDelegate; class GvrDeviceProvider; -class PresentingGvrDelegate; } namespace vr_shell { -class NonPresentingGvrDelegate; - class VrShellDelegate : public device::GvrDelegateProvider { public: VrShellDelegate(JNIEnv* env, jobject obj); @@ -37,8 +35,7 @@ static VrShellDelegate* GetNativeVrShellDelegate(JNIEnv* env, jobject jdelegate); - void SetPresentingDelegate(device::PresentingGvrDelegate* delegate, - gvr_context* context); + void SetDelegate(device::GvrDelegate* delegate, gvr::ViewerType viewer_type); void RemoveDelegate(); void SetPresentResult(JNIEnv* env, @@ -62,29 +59,37 @@ // device::GvrDelegateProvider implementation. void ExitWebVRPresent() override; + void CreateVRDisplayInfo( + const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, + uint32_t device_id) override; private: // device::GvrDelegateProvider implementation. void SetDeviceProvider(device::GvrDeviceProvider* device_provider) override; void ClearDeviceProvider() override; void RequestWebVRPresent(device::mojom::VRSubmitFrameClientPtr submit_client, + device::mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) override; device::GvrDelegate* GetDelegate() override; void SetListeningForActivate(bool listening) override; - void CreateNonPresentingDelegate(); + void GetNextMagicWindowPose( + device::mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) + override; + void OnActivateDisplayHandled(bool will_not_present); std::unique_ptr<VrCoreInfo> MakeVrCoreInfo(JNIEnv* env); - std::unique_ptr<NonPresentingGvrDelegate> non_presenting_delegate_; base::android::ScopedJavaGlobalRef<jobject> j_vr_shell_delegate_; device::GvrDeviceProvider* device_provider_ = nullptr; - device::PresentingGvrDelegate* presenting_delegate_ = nullptr; + device::GvrDelegate* gvr_delegate_ = nullptr; base::Callback<void(bool)> present_callback_; int64_t timebase_nanos_ = 0; double interval_seconds_ = 0; device::mojom::VRSubmitFrameClientPtr submit_client_; + device::mojom::VRPresentationProviderRequest presentation_provider_request_; bool pending_successful_present_request_ = false; + std::unique_ptr<gvr::GvrApi> gvr_api_; base::WeakPtrFactory<VrShellDelegate> weak_ptr_factory_;
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index 4a14fa1..6d63fbbf 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -268,7 +268,7 @@ // to this message will go through some other VSyncProvider. base::ResetAndReturn(&callback_) .Run(nullptr, base::TimeDelta(), -1, - device::mojom::VRVSyncProvider::Status::CLOSING); + device::mojom::VRPresentationProvider::VSyncStatus::CLOSING); } } @@ -386,8 +386,8 @@ } } -void VrShellGl::SubmitWebVRFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) { +void VrShellGl::SubmitFrame(int16_t frame_index, + const gpu::MailboxHolder& mailbox) { DCHECK(submit_client_.get()); TRACE_EVENT0("gpu", "VrShellGl::SubmitWebVRFrame"); @@ -417,9 +417,12 @@ } } -void VrShellGl::SetSubmitClient( - device::mojom::VRSubmitFrameClientPtrInfo submit_client_info) { +void VrShellGl::ConnectPresentingService( + device::mojom::VRSubmitFrameClientPtrInfo submit_client_info, + device::mojom::VRPresentationProviderRequest request) { submit_client_.Bind(std::move(submit_client_info)); + binding_.Close(); + binding_.Bind(std::move(request)); } void VrShellGl::OnContentFrameAvailable() { @@ -450,7 +453,7 @@ gvr_api_ = gvr::GvrApi::WrapNonOwned(gvr_api); controller_.reset(new VrController(gvr_api)); - VrMetricsUtil::LogVrViewerType(gvr_api); + VrMetricsUtil::LogVrViewerType(gvr_api_->GetViewerType()); cardboard_ = (gvr_api_->GetViewerType() == gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD); @@ -536,7 +539,7 @@ webvr_right_viewport_.get()); webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); - browser_->GvrDelegateReady(); + browser_->GvrDelegateReady(gvr_api_->GetViewerType()); } void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) { @@ -1278,7 +1281,7 @@ void VrShellGl::DrawElement(const gfx::Transform& view_proj_matrix, const UiElement& element) { - gfx::Transform transform = view_proj_matrix * element.TransformMatrix(); + gfx::Transform transform = view_proj_matrix * element.transform(); switch (element.fill()) { case Fill::OPAQUE_GRADIENT: { @@ -1326,8 +1329,8 @@ if (first->draw_phase() != second->draw_phase()) { return first->draw_phase() < second->draw_phase(); } else { - return first->TransformMatrix().matrix().get(2, 3) < - second->TransformMatrix().matrix().get(2, 3); + return first->transform().matrix().get(2, 3) < + second->transform().matrix().get(2, 3); } }); @@ -1473,20 +1476,6 @@ } } -void VrShellGl::UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size) { - if (frame_index < 0) { - webvr_left_viewport_->SetSourceUv(UVFromGfxRect(left_bounds)); - webvr_right_viewport_->SetSourceUv(UVFromGfxRect(right_bounds)); - CreateOrResizeWebVRSurface(source_size); - } else { - pending_bounds_.emplace( - frame_index, WebVrBounds(left_bounds, right_bounds, source_size)); - } -} - void VrShellGl::ContentBoundsChanged(int width, int height) { TRACE_EVENT0("gpu", "VrShellGl::ContentBoundsChanged"); content_tex_css_width_ = width; @@ -1539,11 +1528,6 @@ } } -void VrShellGl::OnRequest(device::mojom::VRVSyncProviderRequest request) { - binding_.Close(); - binding_.Bind(std::move(request)); -} - void VrShellGl::GetVSync(GetVSyncCallback callback) { // In surfaceless (reprojecting) rendering, stay locked // to vsync intervals. Otherwise, for legacy Cardboard mode, @@ -1575,6 +1559,20 @@ browser_->ForceExitVr(); } +void VrShellGl::UpdateLayerBounds(int16_t frame_index, + const gfx::RectF& left_bounds, + const gfx::RectF& right_bounds, + const gfx::Size& source_size) { + if (frame_index < 0) { + webvr_left_viewport_->SetSourceUv(UVFromGfxRect(left_bounds)); + webvr_right_viewport_->SetSourceUv(UVFromGfxRect(right_bounds)); + CreateOrResizeWebVRSurface(source_size); + } else { + pending_bounds_.emplace( + frame_index, WebVrBounds(left_bounds, right_bounds, source_size)); + } +} + int64_t VrShellGl::GetPredictedFrameTimeNanos() { int64_t frame_time_micros = vsync_interval_.InMicroseconds(); // If we aim to submit at vsync, that frame will start scanning out @@ -1607,8 +1605,9 @@ webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; webvr_time_pose_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now(); - std::move(callback).Run(std::move(pose), time, frame_index, - device::mojom::VRVSyncProvider::Status::SUCCESS); + std::move(callback).Run( + std::move(pose), time, frame_index, + device::mojom::VRPresentationProvider::VSyncStatus::SUCCESS); } void VrShellGl::CreateVRDisplayInfo(
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index 57252186..c41f27a 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -65,7 +65,7 @@ // This class manages all GLThread owned objects and GL rendering for VrShell. // It is not threadsafe and must only be used on the GL thread. -class VrShellGl : public device::mojom::VRVSyncProvider { +class VrShellGl : public device::mojom::VRPresentationProvider { public: VrShellGl(GlBrowserInterface* browser, gvr_context* gvr_api, @@ -97,20 +97,14 @@ void SetControllerModel(std::unique_ptr<VrControllerModel> model); - void UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size); - void UpdateVSyncInterval(int64_t timebase_nanos, double interval_seconds); - void OnRequest(device::mojom::VRVSyncProviderRequest request); void CreateVRDisplayInfo( const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, uint32_t device_id); - void SubmitWebVRFrame(int16_t frame_index, const gpu::MailboxHolder& mailbox); - void SetSubmitClient( - device::mojom::VRSubmitFrameClientPtrInfo submit_client_info); + void ConnectPresentingService( + device::mojom::VRSubmitFrameClientPtrInfo submit_client_info, + device::mojom::VRPresentationProviderRequest request); private: void GvrInit(gvr_context* gvr_api); @@ -187,8 +181,14 @@ void OnVSync(); - // VRVSyncProvider + // VRPresentationProvider void GetVSync(GetVSyncCallback callback) override; + void SubmitFrame(int16_t frame_index, + const gpu::MailboxHolder& mailbox) override; + void UpdateLayerBounds(int16_t frame_index, + const gfx::RectF& left_bounds, + const gfx::RectF& right_bounds, + const gfx::Size& source_size) override; void ForceExitVr(); @@ -273,7 +273,7 @@ bool pending_vsync_ = false; GetVSyncCallback callback_; bool received_frame_ = false; - mojo::Binding<device::mojom::VRVSyncProvider> binding_; + mojo::Binding<device::mojom::VRPresentationProvider> binding_; device::mojom::VRSubmitFrameClientPtr submit_client_; GlBrowserInterface* browser_;
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc index 156fb72..4c684f4 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -249,7 +249,10 @@ if (data.primary_icon) { shortcut_info_.best_primary_icon_url = data.primary_icon_url; - CreateLauncherIcon(*(data.primary_icon)); + if (webapk_compatible) + NotifyObserver(*data.primary_icon); + else + CreateLauncherIcon(*(data.primary_icon)); return; }
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc index 905b18cc..d7e6a373 100644 --- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc +++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
@@ -67,9 +67,9 @@ if (process_.IsValid()) { // Kill the host process if necessary to make sure we don't leave zombies. - // On OSX base::EnsureProcessTerminated() may block, so we have to post a - // task on the blocking pool. -#if defined(OS_MACOSX) + // On OSX and Fuchsia base::EnsureProcessTerminated() may block, so we have + // to post a task on the blocking pool. +#if defined(OS_MACOSX) || defined(OS_FUCHSIA) base::PostTaskWithTraits( FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, base::BindOnce(&base::EnsureProcessTerminated, Passed(&process_)));
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js index c271af5..8c85cb7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js
@@ -654,12 +654,24 @@ if (!actionNodeSpan) return; var actionNode = actionNodeSpan.node; + var offset = actionNodeSpan.offset; if (actionNode.role === RoleType.INLINE_TEXT_BOX) actionNode = actionNode.parent; actionNode.doDefault(); - if (selectionSpan) { - var start = text.getSpanStart(selectionSpan); - var targetPosition = position - start; + + if (!selectionSpan) + selectionSpan = actionNodeSpan; + + var start = text.getSpanStart(selectionSpan); + var targetPosition = position - start + offset; + + if (actionNode.state.richlyEditable) { + chrome.automation.setDocumentSelection( + { anchorObject: actionNode, + anchorOffset: targetPosition, + focusObject: actionNode, + focusOffset: targetPosition }); + } else { actionNode.setSelection(targetPosition, targetPosition); } },
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js index 4873e59..584adc37 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/desktop_automation_handler.js
@@ -271,6 +271,18 @@ * @param {!AutomationEvent} evt */ onChildrenChanged: function(evt) { + if (evt.target.state.richlyEditable) { + // Generic tree changes within richly editable text e.g. inline text box + // data might require editable text updates. Further note that children + // change events can and do come after text/text selection changes. + var rootEditable = evt.target; + while (rootEditable.parent && rootEditable.parent.state.richlyEditable) + rootEditable = rootEditable.parent; + this.onEditableChanged_(new CustomAutomationEvent( + EventType.TEXT_CHANGED, rootEditable, evt.eventFrom)); + return; + } + if (!this.shouldOutput_(evt)) return;
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js index 80c1815..a07c904 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing.js
@@ -253,17 +253,10 @@ cur.startOffset || 0, cur.endOffset || 0, true)); - - var value = cur.value_; - value.setSpan(new cvox.ValueSpan(0), 0, cur.value_.length); - value.setSpan( - new cvox.ValueSelectionSpan(), cur.startOffset, cur.endOffset); - cvox.ChromeVox.braille.write(new cvox.NavBraille({text: value, - startIndex: cur.startOffset, - endIndex: cur.endOffset})); + this.brailleCurrentRichLine_(); // Finally, queue up any text markers/styles at bounds. - var container = cur.lineContainer_; + var container = cur.startContainer_; if (!container) return; @@ -303,18 +296,15 @@ } // Just output the current line. - if (!cur.lineStart_ || !cur.lineEnd_) - return; - var prevRange = null; - if (prev.lineStart_ && prev.lineEnd_) { - prevRange = new Range( - Cursor.fromNode(prev.lineStart_), Cursor.fromNode(prev.lineEnd_)); - } + cvox.ChromeVox.tts.speak(cur.text, cvox.QueueMode.CATEGORY_FLUSH); + this.brailleCurrentRichLine_(); - new Output().withRichSpeechAndBraille(new Range( - Cursor.fromNode(cur.lineStart_), Cursor.fromNode(cur.lineEnd_)), - prevRange, - Output.EventType.NAVIGATE).go(); + // The state in EditableTextBase needs to get updated with the new line + // contents, so that subsequent intra-line changes get the right state + // transitions. + this.value = cur.text; + this.start = cur.startOffset; + this.end = cur.endOffset; }, /** @@ -366,6 +356,19 @@ } }, + /** @private */ + brailleCurrentRichLine_: function() { + var cur = this.line_; + var value = cur.value_; + value.setSpan(new cvox.ValueSpan(0), 0, cur.value_.length); + value.setSpan( + new cvox.ValueSelectionSpan(), cur.startOffset, cur.endOffset); + cvox.ChromeVox.braille.write(new cvox.NavBraille( + {text: value, + startIndex: cur.startOffset, + endIndex: cur.endOffset})); + }, + /** @override */ describeSelectionChanged: function(evt) { // Ignore end of text announcements. @@ -473,7 +476,11 @@ /** @private {AutomationNode} */ this.lineEnd_; /** @private {AutomationNode|undefined} */ - this.lineContainer_; + this.startContainer_; + /** @private {AutomationNode|undefined} */ + this.lineStartContainer_; + /** @private {number} */ + this.localLineStartContainerOffset_ = 0; this.computeLineData_(); }; @@ -481,32 +488,115 @@ editing.EditableLine.prototype = { /** @private */ computeLineData_: function() { - this.value_ = new Spannable(this.start_.node.name, this.start_); - if (this.start_.node == this.end_.node) - this.value_.setSpan(this.end_, 0, this.start_.node.name.length); + var nameLen = 0; + if (this.start_.node.name) + nameLen = this.start_.node.name.length; + this.value_ = new Spannable(this.start_.node.name || '', this.start_); + if (this.start_.node == this.end_.node) + this.value_.setSpan(this.end_, 0, nameLen); + + // Initialize defaults. this.lineStart_ = this.start_.node; this.lineEnd_ = this.lineStart_; - this.lineContainer_ = this.lineStart_.parent; + this.startContainer_ = this.lineStart_.parent; + this.lineStartContainer_ = this.lineStart_.parent; - // Annotate each chunk with its associated node. + // Annotate each chunk with its associated inline text box node. this.value_.setSpan(this.lineStart_, 0, this.lineStart_.name.length); - while (this.lineStart_.previousOnLine) { - this.lineStart_ = this.lineStart_.previousOnLine; - var prepend = new Spannable(this.lineStart_.name, this.lineStart_); + // If the current selection is not on an inline text box (e.g. an image), + // return early here so that the line contents are just the node. This is + // pending the ability to show non-text leaf inline objects. + if (this.lineStart_.role != RoleType.INLINE_TEXT_BOX) + return; + + // Also, track their static text parents. + var parents = [this.startContainer_]; + + // Compute the start of line. + var lineStart = this.lineStart_; + while (lineStart.previousOnLine && lineStart.previousOnLine.role) { + lineStart = lineStart.previousOnLine; + if (lineStart.role != RoleType.INLINE_TEXT_BOX) + continue; + + this.lineStart_ = lineStart; + if (parents[0] != lineStart.parent) + parents.unshift(lineStart.parent); + + var prepend = new Spannable(lineStart.name, lineStart); prepend.append(this.value_); this.value_ = prepend; } + this.lineStartContainer_ = this.lineStart_.parent; - while (this.lineEnd_.nextOnLine) { - this.lineEnd_ = this.lineEnd_.nextOnLine; + var lineEnd = this.lineEnd_; + while (lineEnd.nextOnLine && lineEnd.nextOnLine.role) { + lineEnd = lineEnd.nextOnLine; + if (lineEnd.role != RoleType.INLINE_TEXT_BOX) + continue; - var annotation = this.lineEnd_; - if (this.lineEnd_ == this.end_.node) + this.lineEnd_ = lineEnd; + if (parents[parents.length - 1] != lineEnd.parent) + parents.push(this.lineEnd_.parent); + + var annotation = lineEnd; + if (lineEnd == this.end_.node) annotation = this.end_; - this.value_.append(new Spannable(this.lineEnd_.name, annotation)); + this.value_.append(new Spannable(lineEnd.name, annotation)); + } + + // Finally, annotate with all parent static texts as NodeSpan's so that + // braille routing can key properly into the node with an offset. + // Note that both line start and end needs to account for + // potential offsets into the static texts as follows. + var textCountBeforeLineStart = 0, textCountAfterLineEnd = 0; + var finder = this.lineStart_; + while (finder.previousSibling) { + finder = finder.previousSibling; + textCountBeforeLineStart += finder.name.length; + } + this.localLineStartContainerOffset_ = textCountBeforeLineStart; + + finder = this.lineEnd_; + while (finder.nextSibling) { + finder = finder.nextSibling; + textCountAfterLineEnd += finder.name.length; + } + + var len = 0; + for (var i = 0; i < parents.length; i++) { + var parent = parents[i]; + + if (!parent.name) + continue; + + var prevLen = len; + + var currentLen = parent.name.length; + var offset = 0; + + // Subtract off the text count before when at the start of line. + if (i == 0) { + currentLen -= textCountBeforeLineStart; + offset = textCountBeforeLineStart; + } + + // Subtract text count after when at the end of the line. + if (i == parents.length - 1) + currentLen -= textCountAfterLineEnd; + + len += currentLen; + + try { + this.value_.setSpan(new Output.NodeSpan(parent, offset), prevLen, len); + + // Also, annotate this span if it is associated with line containre. + if (parent == this.startContainer_) + this.value_.setSpan(parent, prevLen, len); + } catch (e) {} } }, @@ -528,6 +618,7 @@ /** * Gets the selection offset based on the parent's text. + * The parent is expected to be static text. * @return {number} */ get localStartOffset() { @@ -536,6 +627,7 @@ /** * Gets the selection offset based on the parent's text. + * The parent is expected to be static text. * @return {number} */ get localEndOffset() { @@ -543,36 +635,25 @@ }, /** - * Gets the start offset of the line, relative to the container's text. - * @return {number} - */ - get containerLineStartOffset() { - // When the container start offset is larger, the start offset is usually - // part of a line wrap, so the two offsets differ. - // When the container start offset is smaller, there is usually more line - // content before the container accounted for in start offset. - // Taking the difference either way will give us the offset at which the - // line begins. - return Math.abs(this.localContainerStartOffset_ - this.startOffset); - }, - - /** * Gets the start offset of the container, relative to the line text content. + * The container refers to the static text parenting the inline text box. * @return {number} */ get containerStartOffset() { - return this.value_.getSpanStart(this.lineContainer_.firstChild); + return this.value_.getSpanStart(this.startContainer_); }, /** * Gets the end offset of the container, relative to the line text content. + * The container refers to the static text parenting the inline text box. * @return {number} */ get containerEndOffset() { - return this.value_.getSpanEnd(this.lineContainer_.lastChild) - 1; + return this.value_.getSpanEnd(this.startContainer_) - 1; }, /** + * The text content of this line. * @return {string} The text of this line. */ get text() { @@ -586,11 +667,11 @@ */ equals: function(otherLine) { // Equality is intentionally loose here as any of the state nodes can be - // invalidated at any time. - return (otherLine.lineStart_ == this.lineStart_ && - otherLine.lineEnd_ == this.lineEnd_) || - (otherLine.lineContainer_ == this.lineContainer_ && - otherLine.containerLineStartOffset == this.containerLineStartOffset); + // invalidated at any time. We rely upon the start/anchor of the line + // staying the same. + return otherLine.lineStartContainer_ == this.lineStartContainer_ && + otherLine.localLineStartContainerOffset_ == + this.localLineStartContainerOffset_; } };
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs index 6c5deea4..af6ebc8 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/editing_test.extjs
@@ -246,14 +246,14 @@ .expectSpeech('\n') .expectBraille('\n') .call(moveByLine) - .expectSpeech('This is a ', 'test', 'Link', ' of rich text') - .expectBraille('This is a test lnk of rich text') + .expectSpeech('This is a test of rich text') + .expectBraille('This is a test of rich text') .call(moveByLine) .expectSpeech('\n') .expectBraille('\n') .call(moveByLine) - .expectSpeech('hello', 'Heading 2') - .expectBraille('hello h2') + .expectSpeech('hello') + .expectBraille('hello') .replay(); }); input.focus(); @@ -372,3 +372,185 @@ input.focus(); }); }); + +TEST_F('EditingTest', 'EditableLineOneStaticText', function() { + this.runWithLoadedTree(function() {/*! + <p contenteditable style="word-spacing:100000px">this is a test</p> + */}, function(root) { + var staticText = root.find({role: RoleType.STATIC_TEXT}); + + var e = new editing.EditableLine(staticText, 0, staticText, 0); + assertEquals('this ', e.text); + + assertEquals(0, e.startOffset); + assertEquals(0, e.endOffset); + assertEquals(0, e.localStartOffset); + assertEquals(0, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(4, e.containerEndOffset); + + e = new editing.EditableLine(staticText, 1, staticText, 1); + assertEquals('this ', e.text); + + assertEquals(1, e.startOffset); + assertEquals(1, e.endOffset); + assertEquals(1, e.localStartOffset); + assertEquals(1, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(4, e.containerEndOffset); + + e = new editing.EditableLine(staticText, 5, staticText, 5); + assertEquals('is ', e.text); + + assertEquals(0, e.startOffset); + assertEquals(0, e.endOffset); + assertEquals(0, e.localStartOffset); + assertEquals(0, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(2, e.containerEndOffset); + + e = new editing.EditableLine(staticText, 7, staticText, 7); + assertEquals('is ', e.text); + + assertEquals(2, e.startOffset); + assertEquals(2, e.endOffset); + assertEquals(2, e.localStartOffset); + assertEquals(2, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(2, e.containerEndOffset); + }); +}); + +TEST_F('EditingTest', 'EditableLineTwoStaticTexts', function() { + this.runWithLoadedTree(function() {/*! + <p contenteditable>hello <b>world</b></p> + */}, function(root) { + var text = root.find({role: RoleType.STATIC_TEXT}); + var bold = text.nextSibling; + + var e = new editing.EditableLine(text, 0, text, 0); + assertEquals('hello world', e.text); + + assertEquals(0, e.startOffset); + assertEquals(0, e.endOffset); + assertEquals(0, e.localStartOffset); + assertEquals(0, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(5, e.containerEndOffset); + + e = new editing.EditableLine(text, 5, text, 5); + assertEquals('hello world', e.text); + + assertEquals(5, e.startOffset); + assertEquals(5, e.endOffset); + assertEquals(5, e.localStartOffset); + assertEquals(5, e.localEndOffset); + + assertEquals(0, e.containerStartOffset); + assertEquals(5, e.containerEndOffset); + + e = new editing.EditableLine(bold, 0, bold, 0); + assertEquals('hello world', e.text); + + assertEquals(6, e.startOffset); + assertEquals(6, e.endOffset); + assertEquals(0, e.localStartOffset); + assertEquals(0, e.localEndOffset); + + assertEquals(6, e.containerStartOffset); + assertEquals(10, e.containerEndOffset); + + e = new editing.EditableLine(bold, 4, bold, 4); + assertEquals('hello world', e.text); + + assertEquals(10, e.startOffset); + assertEquals(10, e.endOffset); + assertEquals(4, e.localStartOffset); + assertEquals(4, e.localEndOffset); + + assertEquals(6, e.containerStartOffset); + assertEquals(10, e.containerEndOffset); + }); +}); + +TEST_F('EditingTest', 'EditableLineEquality', function() { + this.runWithLoadedTree(function() {/*! + <div contenteditable role="textbox"> + <p style="word-spacing:100000px">this is a test</p> + <p>hello <b>world</b></p> + </div> + */}, function(root) { + var thisIsATest = root.findAll({role: RoleType.PARAGRAPH})[0].firstChild; + var hello = root.findAll({role: RoleType.PARAGRAPH})[1].firstChild; + var world = root.findAll({role: RoleType.PARAGRAPH})[1].lastChild; + + // The same position -- sanity check. + var e1 = new editing.EditableLine(thisIsATest, 0, thisIsATest, 0); + assertEquals('this ', e1.text); + assertTrue(e1.equals(e1)); + + // Offset into the same soft line. + var e2 = new editing.EditableLine(thisIsATest, 1, thisIsATest, 1); + assertTrue(e1.equals(e2)); + + // Boundary. + e2 = new editing.EditableLine(thisIsATest, 4, thisIsATest, 4); + assertTrue(e1.equals(e2)); + + // Offsets into different soft lines. + e2 = new editing.EditableLine(thisIsATest, 5, thisIsATest, 5); + assertEquals('is ', e2.text); + assertFalse(e1.equals(e2)); + + // Sanity check; second soft line. + assertTrue(e2.equals(e2)); + + // Different offsets into second soft line. + e1 = new editing.EditableLine(thisIsATest, 6, thisIsATest, 6); + assertTrue(e1.equals(e2)); + + // Boundary. + e1 = new editing.EditableLine(thisIsATest, 7, thisIsATest, 7); + assertTrue(e1.equals(e2)); + + // Third line. + e1 = new editing.EditableLine(thisIsATest, 8, thisIsATest, 8); + assertEquals('a ', e1.text); + assertFalse(e1.equals(e2)); + + // Last line. + e2 = new editing.EditableLine(thisIsATest, 10, thisIsATest, 10); + assertEquals('test', e2.text); + assertFalse(e1.equals(e2)); + + // Boundary. + e1 = new editing.EditableLine(thisIsATest, 13, thisIsATest, 13); + assertTrue(e1.equals(e2)); + + // Cross into new paragraph. + e2 = new editing.EditableLine(hello, 0, hello, 0); + assertEquals('hello world', e2.text); + assertFalse(e1.equals(e2)); + + // On same node, with multi-static text line. + e1 = new editing.EditableLine(hello, 1, hello, 1); + assertTrue(e1.equals(e2)); + + // On same node, with multi-static text line; boundary. + e1 = new editing.EditableLine(hello, 5, hello, 5); + assertTrue(e1.equals(e2)); + + // On different node, with multi-static text line. + e1 = new editing.EditableLine(world, 1, world, 1); + assertTrue(e1.equals(e2)); + + // Another mix of lines. + e2 = new editing.EditableLine(thisIsATest, 9, thisIsATest, 9); + assertFalse(e1.equals(e2)); + }); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 6e7ff8d..fb5d99d 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -716,10 +716,12 @@ * {@code AutomationNode} constructor isn't exposed in the API, this class is * used to allow instanceof checks on these annotations. * @param {!AutomationNode} node + * @param {number=} opt_offset Offsets into the node's text. Defaults to 0. * @constructor */ -Output.NodeSpan = function(node) { +Output.NodeSpan = function(node, opt_offset) { this.node = node; + this.offset = opt_offset ? opt_offset : 0; }; /**
diff --git a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html index ae09f68..37465ce 100644 --- a/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html +++ b/chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html
@@ -110,8 +110,7 @@ } .digit-button.backspace-button:not([has-content]) { - color: #000; - opacity: 0.26; + opacity: 0.34; } .digit-button inner-text {
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.html b/chrome/browser/resources/md_bookmarks/command_manager.html index a57c510..1a87572 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.html +++ b/chrome/browser/resources/md_bookmarks/command_manager.html
@@ -2,6 +2,7 @@ <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/html/cr/ui/command.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <link rel="import" href="chrome://bookmarks/edit_dialog.html"> <link rel="import" href="chrome://bookmarks/shared_style.html">
diff --git a/chrome/browser/resources/md_bookmarks/command_manager.js b/chrome/browser/resources/md_bookmarks/command_manager.js index 24c26d5..e50b808 100644 --- a/chrome/browser/resources/md_bookmarks/command_manager.js +++ b/chrome/browser/resources/md_bookmarks/command_manager.js
@@ -62,19 +62,19 @@ this.boundOnKeydown_ = this.onKeydown_.bind(this); document.addEventListener('keydown', this.boundOnKeydown_); - /** @private {Object<Command, string>} */ + /** @private {Object<Command, cr.ui.KeyboardShortcutList>} */ this.shortcuts_ = {}; - this.shortcuts_[Command.EDIT] = cr.isMac ? 'enter' : 'f2'; - this.shortcuts_[Command.COPY] = cr.isMac ? 'meta+c' : 'ctrl+c'; - this.shortcuts_[Command.DELETE] = - cr.isMac ? 'delete backspace' : 'delete'; - this.shortcuts_[Command.OPEN_NEW_TAB] = - cr.isMac ? 'meta+enter' : 'ctrl+enter'; - this.shortcuts_[Command.OPEN_NEW_WINDOW] = 'shift+enter'; - this.shortcuts_[Command.OPEN] = cr.isMac ? 'meta+down' : 'enter'; - this.shortcuts_[Command.UNDO] = cr.isMac ? 'meta+z' : 'ctrl+z'; - this.shortcuts_[Command.REDO] = - cr.isMac ? 'meta+shift+z' : 'ctrl+y ctrl+shift+z'; + + this.addShortcut_(Command.EDIT, 'F2', 'Enter'); + this.addShortcut_(Command.COPY, 'Ctrl|c', 'Meta|c'); + this.addShortcut_(Command.DELETE, 'Delete', 'Delete Backspace'); + + this.addShortcut_(Command.OPEN, 'Enter', 'Meta|ArrowDown Meta|o'); + this.addShortcut_(Command.OPEN_NEW_TAB, 'Ctrl|Enter', 'Meta|Enter'); + this.addShortcut_(Command.OPEN_NEW_WINDOW, 'Shift|Enter'); + + this.addShortcut_(Command.UNDO, 'Ctrl|z', 'Meta|z'); + this.addShortcut_(Command.REDO, 'Ctrl|y Ctrl|Shift|Z', 'Meta|Shift|Z'); }, detached: function() { @@ -189,11 +189,12 @@ * @param {!Set<string>} itemIds */ handle: function(command, itemIds) { + var state = this.getState(); switch (command) { case Command.EDIT: var id = Array.from(itemIds)[0]; /** @type {!BookmarksEditDialogElement} */ (this.$.editDialog.get()) - .showEditDialog(this.getState().nodes[id]); + .showEditDialog(state.nodes[id]); break; case Command.COPY: var idList = Array.from(itemIds); @@ -204,7 +205,7 @@ break; case Command.DELETE: var idList = Array.from(this.minimizeDeletionSet_(itemIds)); - var title = this.getState().nodes[idList[0]].title; + var title = state.nodes[idList[0]].title; var labelPromise = cr.sendWithPromise( 'getPluralString', 'toastItemsDeleted', idList.length); chrome.bookmarkManagerPrivate.removeTrees(idList, function() { @@ -239,8 +240,8 @@ }); if (isFolder) { var folderId = Array.from(itemIds)[0]; - this.dispatch(bookmarks.actions.selectFolder( - folderId, this.getState().nodes)); + this.dispatch( + bookmarks.actions.selectFolder(folderId, state.nodes)); } else { this.openUrls_(this.expandUrls_(itemIds), command); } @@ -251,7 +252,7 @@ }, /** - * @param {Event} e + * @param {!Event} e * @param {!Set<string>} itemIds * @return {boolean} True if the event was handled, triggering a keyboard * shortcut. @@ -259,9 +260,7 @@ handleKeyEvent: function(e, itemIds) { for (var commandName in this.shortcuts_) { var shortcut = this.shortcuts_[commandName]; - if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys( - e, shortcut) && - this.canExecute(commandName, itemIds)) { + if (shortcut.matchesEvent(e) && this.canExecute(commandName, itemIds)) { this.handle(commandName, itemIds); e.stopPropagation(); @@ -277,6 +276,19 @@ // Private functions: /** + * Register a keyboard shortcut for a command. + * @param {Command} command Command that the shortcut will trigger. + * @param {string} shortcut Keyboard shortcut, using the syntax of + * cr/ui/command.js. + * @param {string=} macShortcut If set, enables a replacement shortcut for + * Mac. + */ + addShortcut_: function(command, shortcut, macShortcut) { + var shortcut = (cr.isMac && macShortcut) ? macShortcut : shortcut; + this.shortcuts_[command] = new cr.ui.KeyboardShortcutList(shortcut); + }, + + /** * Minimize the set of |itemIds| by removing any node which has an ancestor * node already in the set. This ensures that instead of trying to delete * both a node and its descendant, we will only try to delete the topmost
diff --git a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp index ec5928a..6f9e4eaf 100644 --- a/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp +++ b/chrome/browser/resources/md_bookmarks/compiled_resources2.gyp
@@ -44,6 +44,7 @@ '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:command', '<(EXTERNS_GYP):bookmark_manager_private', 'edit_dialog', 'store_client',
diff --git a/chrome/browser/resources/md_history/browser_service.js b/chrome/browser/resources/md_history/browser_service.js index a2a09ad4..9ee3c8e 100644 --- a/chrome/browser/resources/md_history/browser_service.js +++ b/chrome/browser/resources/md_history/browser_service.js
@@ -92,9 +92,9 @@ }, /** - * Record an action in UMA. - * @param {string} action The name of the action to be logged. - */ + * Record an action in UMA. + * @param {string} action The name of the action to be logged. + */ recordAction: function(action) { if (action.indexOf('_') == -1) action = 'HistoryPage_' + action;
diff --git a/chrome/browser/resources/md_history/router.js b/chrome/browser/resources/md_history/router.js index b20d4e2..29f7512 100644 --- a/chrome/browser/resources/md_history/router.js +++ b/chrome/browser/resources/md_history/router.js
@@ -9,7 +9,7 @@ selectedPage: { type: String, notify: true, - observer: 'selectedPageChanged_' + observer: 'selectedPageChanged_', }, /** @type {QueryState} */
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html index 99da789..7d71e83b 100644 --- a/chrome/browser/resources/settings/search_engines_page/search_engines_list.html +++ b/chrome/browser/resources/settings/search_engines_page/search_engines_list.html
@@ -42,7 +42,9 @@ } .icon-placeholder { - width: calc(var(--iron-icon-width) + 2 * 10px); + -webkit-margin-end: 0; + -webkit-margin-start: var(--cr-icon-button-margin-start); + width: var(--cr-icon-ripple-size); } </style> <div id="outer">
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm index 5ef04a2..e565ec1 100644 --- a/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm
@@ -11,6 +11,7 @@ #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" #import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/test/menu_test_observer.h" #import "ui/events/test/cocoa_test_event_utils.h" namespace { @@ -22,72 +23,6 @@ NSWindow* g_key_window = nil; } // namespace -@interface ContextMenuController : NSObject<NSMenuDelegate> { - @private - NSMenu* menu_; - NSWindow* window_; - BOOL isMenuOpen_; - BOOL didOpen_; -} - -- (id)initWithMenu:(NSMenu*)menu andWindow:(NSWindow*)window; - -- (BOOL)isMenuOpen; -- (BOOL)didOpen; -- (BOOL)isWindowVisible; - -// NSMenuDelegate methods -- (void)menuWillOpen:(NSMenu*)menu; -- (void)menuDidClose:(NSMenu*)menu; - -@end - -@implementation ContextMenuController - -- (id)initWithMenu:(NSMenu*)menu andWindow:(NSWindow*)window { - if (self = [super init]) { - menu_ = menu; - window_ = window; - isMenuOpen_ = NO; - didOpen_ = NO; - [menu_ setDelegate:self]; - } - return self; -} - -- (BOOL)isMenuOpen { - return isMenuOpen_; -} - -- (BOOL)didOpen { - return didOpen_; -} - -- (BOOL)isWindowVisible { - if (window_) { - return [window_ isVisible]; - } - return NO; -} - -- (void)menuWillOpen:(NSMenu*)menu { - isMenuOpen_ = YES; - didOpen_ = NO; - - NSArray* modes = @[NSEventTrackingRunLoopMode, NSDefaultRunLoopMode]; - [menu_ performSelector:@selector(cancelTracking) - withObject:nil - afterDelay:0.1 - inModes:modes]; -} - -- (void)menuDidClose:(NSMenu*)menu { - isMenuOpen_ = NO; - didOpen_ = YES; -} - -@end - // A helper class to swizzle [NSApplication keyWindow]. @interface FakeKeyWindow : NSObject @property(readonly) NSWindow* keyWindow; @@ -326,34 +261,34 @@ [context_menu addItemWithTitle:@"ContextMenuTest" action:nil keyEquivalent:@""]; - base::scoped_nsobject<ContextMenuController> menu_controller( - [[ContextMenuController alloc] initWithMenu:context_menu - andWindow:window]); // Set the menu as the contextual menu of contentView of test_window(). [[test_window() contentView] setMenu:context_menu]; + base::scoped_nsobject<MenuTestObserver> menu_observer( + [[MenuTestObserver alloc] initWithMenu:context_menu]); + [menu_observer setCloseAfterOpening:YES]; + [menu_observer setOpenCallback:^(MenuTestObserver* observer) { + // Verify bubble's window is closed when contextual menu is open. + EXPECT_TRUE([observer isOpen]); + EXPECT_FALSE([window isVisible]); + }]; + // RightMouseDown in test_window() would close the bubble window and then // dispaly the contextual menu. NSEvent* event = cocoa_test_event_utils::RightMouseDownAtPointInWindow( NSMakePoint(10, 10), test_window()); - // Verify bubble's window is closed when contextual menu is open. - CFRunLoopPerformBlock(CFRunLoopGetCurrent(), NSEventTrackingRunLoopMode, ^{ - EXPECT_TRUE([menu_controller isMenuOpen]); - EXPECT_FALSE([menu_controller isWindowVisible]); - }); - EXPECT_FALSE([menu_controller isMenuOpen]); - EXPECT_FALSE([menu_controller didOpen]); + EXPECT_FALSE([menu_observer isOpen]); + EXPECT_FALSE([menu_observer didOpen]); [NSApp sendEvent:event]; // When we got here, menu has already run its RunLoop. - // See -[ContextualMenuController menuWillOpen:]. EXPECT_FALSE([window isVisible]); - EXPECT_FALSE([menu_controller isMenuOpen]); - EXPECT_TRUE([menu_controller didOpen]); + EXPECT_FALSE([menu_observer isOpen]); + EXPECT_TRUE([menu_observer didOpen]); } // Test that the bubble is not dismissed when it has an attached sheet, or when
diff --git a/chrome/browser/ui/webui/version_ui.cc b/chrome/browser/ui/webui/version_ui.cc index 81fe7b3..2ef9c38 100644 --- a/chrome/browser/ui/webui/version_ui.cc +++ b/chrome/browser/ui/webui/version_ui.cc
@@ -162,6 +162,8 @@ html_source->AddString(version_ui::kUpdateCohortName, l10n_util::GetStringFUTF16( IDS_VERSION_UI_COHORT_NAME, update_cohort_name)); + } else { + html_source->AddString(version_ui::kUpdateCohortName, std::string()); } #endif // defined(OS_WIN)
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 0be2d6c..26d77c4 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -196,6 +196,7 @@ "//chrome/common:constants", "//chrome/common/media_router/mojo:dial_utility_interfaces", "//chrome/common/net", + "//chrome/common/profiling", "//chrome/common/safe_browsing:proto", "//chrome/installer/util:with_no_strings", "//components/autofill/content/common:ipc_traits",
diff --git a/chrome/common/profiling/BUILD.gn b/chrome/common/profiling/BUILD.gn new file mode 100644 index 0000000..ff59ef5 --- /dev/null +++ b/chrome/common/profiling/BUILD.gn
@@ -0,0 +1,27 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//chrome/common/features.gni") + +if (enable_oop_heap_profiling) { + static_library("profiling") { + sources = [ + "memlog_sender_pipe.h", + "memlog_sender_pipe_win.cc", + "memlog_sender_pipe_win.h", + "memlog_stream.cc", + "memlog_stream.h", + ] + + deps = [ + "//base", + "//base:debugging_flags", + "//chrome/common:constants", + ] + } +} else { + # Dummy group so this target can be unconditionally depended on. + group("profiling") { + } +}
diff --git a/chrome/common/profiling/memlog_sender_pipe.h b/chrome/common/profiling/memlog_sender_pipe.h new file mode 100644 index 0000000..ba2653e --- /dev/null +++ b/chrome/common/profiling/memlog_sender_pipe.h
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_H_ +#define CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_H_ + +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "chrome/common/profiling/memlog_sender_pipe_win.h" +#endif + +#endif // CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_H_
diff --git a/chrome/common/profiling/memlog_sender_pipe_win.cc b/chrome/common/profiling/memlog_sender_pipe_win.cc new file mode 100644 index 0000000..746ccfd --- /dev/null +++ b/chrome/common/profiling/memlog_sender_pipe_win.cc
@@ -0,0 +1,59 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/profiling/memlog_sender_pipe_win.h" + +#include "base/logging.h" +#include "chrome/common/profiling/memlog_stream.h" + +namespace profiling { + +MemlogSenderPipe::MemlogSenderPipe(const base::string16& pipe_id) + : pipe_id_(pipe_id), handle_(INVALID_HANDLE_VALUE) {} + +MemlogSenderPipe::~MemlogSenderPipe() { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); +} + +bool MemlogSenderPipe::Connect() { + DCHECK(handle_ == INVALID_HANDLE_VALUE); + + base::string16 pipe_name = kWindowsPipePrefix; + pipe_name.append(pipe_id_); + + const int kMaxWaitMS = 30000; + ULONGLONG timeout_ticks = ::GetTickCount64() + kMaxWaitMS; + do { + if (!::WaitNamedPipe(pipe_name.c_str(), kMaxWaitMS)) { + // Since it will wait "forever", the only time WaitNamedPipe should fail + // is if the pipe doesn't exist. + return false; + } + // This is a single-direction pipe so we don't specify GENERIC_READ, but + // MSDN says we need FILE_READ_ATTRIBUTES. + handle_ = ::CreateFile(pipe_name.c_str(), + FILE_READ_ATTRIBUTES | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, NULL); + // Need to loop since there is a race condition waiting for a connection to + // be available and actually connecting to it. + } while (handle_ == INVALID_HANDLE_VALUE && + ::GetTickCount64() < timeout_ticks); + + return handle_ != INVALID_HANDLE_VALUE; +} + +bool MemlogSenderPipe::Send(const void* data, size_t sz) { + // The pipe uses a blocking wait mode (it doesn't specify PIPE_NOWAIT) so + // WriteFile should do only complete writes. + // + // Note: don't use logging here (CHECK, DCHECK) because they will allocate, + // and this function is called from within a malloc hook. + DWORD bytes_written = 0; + if (!::WriteFile(handle_, data, static_cast<DWORD>(sz), &bytes_written, NULL)) + return false; + return true; +} + +} // namespace profiling
diff --git a/chrome/common/profiling/memlog_sender_pipe_win.h b/chrome/common/profiling/memlog_sender_pipe_win.h new file mode 100644 index 0000000..9abeb17 --- /dev/null +++ b/chrome/common/profiling/memlog_sender_pipe_win.h
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_WIN_H_ +#define CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_WIN_H_ + +#include <windows.h> + +#include "base/macros.h" +#include "base/strings/string16.h" + +namespace profiling { + +class MemlogSenderPipe { + public: + explicit MemlogSenderPipe(const base::string16& pipe_id); + ~MemlogSenderPipe(); + + bool Connect(); + + bool Send(const void* data, size_t sz); + + private: + base::string16 pipe_id_; + + HANDLE handle_; + + DISALLOW_COPY_AND_ASSIGN(MemlogSenderPipe); +}; + +} // namespace profiling + +#endif // CHROME_COMMON_PROFILING_MEMLOG_SENDER_PIPE_WIN_H_
diff --git a/chrome/common/profiling/memlog_stream.cc b/chrome/common/profiling/memlog_stream.cc new file mode 100644 index 0000000..f6234f4 --- /dev/null +++ b/chrome/common/profiling/memlog_stream.cc
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/profiling/memlog_stream.h" + +namespace profiling { + +#if defined(OS_WIN) +const wchar_t kWindowsPipePrefix[] = L"\\\\.\\pipe\\chrome_mem."; +#endif // OS_WIN + +} // namespace profiling
diff --git a/chrome/common/profiling/memlog_stream.h b/chrome/common/profiling/memlog_stream.h new file mode 100644 index 0000000..7a9e98d --- /dev/null +++ b/chrome/common/profiling/memlog_stream.h
@@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_PROFILING_MEMLOG_STREAM_H_ +#define CHROME_COMMON_PROFILING_MEMLOG_STREAM_H_ + +#include "build/build_config.h" + +namespace profiling { + +#if defined(OS_WIN) +// Prefix for pipe name for communicating between chrome processes and the +// memlog process. The pipe ID is appended to this to get the pipe name. +extern const wchar_t kWindowsPipePrefix[]; +#endif // OS_WIN + +} // namespace profiling + +#endif // CHROME_COMMON_PROFILING_MEMLOG_STREAM_H_
diff --git a/chrome/profiling/BUILD.gn b/chrome/profiling/BUILD.gn index 097b41e..3a273e2 100644 --- a/chrome/profiling/BUILD.gn +++ b/chrome/profiling/BUILD.gn
@@ -7,6 +7,11 @@ if (enable_oop_heap_profiling) { static_library("profiling") { sources = [ + "memlog_receiver_pipe_server_win.cc", + "memlog_receiver_pipe_server_win.h", + "memlog_receiver_pipe_win.cc", + "memlog_receiver_pipe_win.h", + "memlog_stream_receiver.h", "profiling_globals.cc", "profiling_globals.h", "profiling_main.cc",
diff --git a/chrome/profiling/memlog_receiver_pipe_server_win.cc b/chrome/profiling/memlog_receiver_pipe_server_win.cc new file mode 100644 index 0000000..cf426f4 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_server_win.cc
@@ -0,0 +1,84 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/profiling/memlog_receiver_pipe_server_win.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/common/profiling/memlog_stream.h" + +namespace profiling { + +namespace { + +// Use a large buffer for our pipe. We don't want the sender to block +// if at all possible since it will slow the app down quite a bit. Windows +// seemed to max out a 64K per read when testing larger sizes, so use that. +const int kBufferSize = 1024 * 64; + +} // namespace + +MemlogReceiverPipeServer::MemlogReceiverPipeServer( + base::TaskRunner* io_runner, + const std::string& pipe_id, + NewConnectionCallback on_new_conn) + : io_runner_(io_runner), + pipe_id_(base::ASCIIToUTF16(pipe_id)), + on_new_connection_(on_new_conn) {} + +MemlogReceiverPipeServer::~MemlogReceiverPipeServer() { + // TODO(brettw) we should ensure this destructor is not called when there are + // pending I/O operations as per RegisterIOHandler documentation. +} + +void MemlogReceiverPipeServer::Start() { + // TODO(brettw) this should perhaps not be async in case the subprocess + // launches and tries to connect before the first pipe instance is created. + io_runner_->PostTask( + FROM_HERE, + base::Bind(&MemlogReceiverPipeServer::ScheduleNewConnection, this, true)); +} + +base::string16 MemlogReceiverPipeServer::GetPipeName() const { + base::string16 pipe_name(kWindowsPipePrefix); + pipe_name.append(pipe_id_); + return pipe_name; +} + +HANDLE MemlogReceiverPipeServer::CreatePipeInstance(bool first_instance) const { + base::string16 pipe_name = GetPipeName(); + + DWORD open_mode = PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED; + if (first_instance) + open_mode |= FILE_FLAG_FIRST_PIPE_INSTANCE; + + return ::CreateNamedPipe( + pipe_name.c_str(), open_mode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, + PIPE_UNLIMITED_INSTANCES, kBufferSize, kBufferSize, 5000, NULL); +} + +void MemlogReceiverPipeServer::ScheduleNewConnection(bool first_instance) { + DCHECK(!current_); + // Need Unretained to avoid creating a reference cycle. + current_ = base::MakeUnique<MemlogReceiverPipe::CompletionThunk>( + CreatePipeInstance(first_instance), + base::BindRepeating(&MemlogReceiverPipeServer::OnIOCompleted, + base::Unretained(this))); + ::ConnectNamedPipe(current_->handle(), current_->overlapped()); +} + +void MemlogReceiverPipeServer::OnIOCompleted(size_t bytes_transfered, + DWORD error) { + scoped_refptr<MemlogReceiverPipe> pipe( + new MemlogReceiverPipe(std::move(current_))); + ScheduleNewConnection(false); + + if (!on_new_connection_.is_null()) + on_new_connection_.Run(pipe); + pipe->StartReadingOnIOThread(); +} + +} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe_server_win.h b/chrome/profiling/memlog_receiver_pipe_server_win.h new file mode 100644 index 0000000..c6ace10 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_server_win.h
@@ -0,0 +1,67 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_WIN_H_ +#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_WIN_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_win.h" +#include "base/strings/string16.h" +#include "chrome/profiling/memlog_receiver_pipe_win.h" + +namespace base { +class TaskRunner; +} // namespace base + +namespace profiling { + +class MemlogReceiverPipe; + +// This class listens for new pipe connections and creates new +// MemlogReceiverPipe objects for each one. +class MemlogReceiverPipeServer + : public base::RefCountedThreadSafe<MemlogReceiverPipeServer> { + public: + using NewConnectionCallback = + base::RepeatingCallback<void(scoped_refptr<MemlogReceiverPipe>)>; + + // |io_runner| is the task runner for the I/O thread. When a new connection is + // established, the |on_new_conn| callback is called with the pipe. + MemlogReceiverPipeServer(base::TaskRunner* io_runner, + const std::string& pipe_id, + NewConnectionCallback on_new_conn); + ~MemlogReceiverPipeServer(); + + void set_on_new_connection(NewConnectionCallback on_new_connection) { + on_new_connection_ = on_new_connection; + } + + // Starts the server which opens the pipe and begins accepting connections. + void Start(); + + private: + base::string16 GetPipeName() const; + + HANDLE CreatePipeInstance(bool first_instance) const; + + // Called on the IO thread. + void ScheduleNewConnection(bool first_instance); + + void OnIOCompleted(size_t bytes_transfered, DWORD error); + + scoped_refptr<base::TaskRunner> io_runner_; + base::string16 pipe_id_; + NewConnectionCallback on_new_connection_; + + // Current connection we're waiting on creation for. + std::unique_ptr<MemlogReceiverPipe::CompletionThunk> current_; +}; + +} // namespace profiling + +#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_SERVER_WIN_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_win.cc b/chrome/profiling/memlog_receiver_pipe_win.cc new file mode 100644 index 0000000..38e6221 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_win.cc
@@ -0,0 +1,119 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/profiling/memlog_receiver_pipe_win.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread.h" +#include "chrome/profiling/memlog_stream_receiver.h" + +namespace profiling { + +namespace { + +// Use a large buffer for our pipe. We don't want the sender to block +// if at all possible since it will slow the app down quite a bit. Windows +// seems to max out a 64K per read so we use that (larger would be better if it +// worked). +const int kReadBufferSize = 1024 * 64; + +} // namespace + +MemlogReceiverPipe::CompletionThunk::CompletionThunk(HANDLE handle, Callback cb) + : handle_(handle), callback_(cb) { + base::MessageLoopForIO::current()->RegisterIOHandler(handle, this); + ZeroOverlapped(); +} + +MemlogReceiverPipe::CompletionThunk::~CompletionThunk() { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); +} + +void MemlogReceiverPipe::CompletionThunk::ZeroOverlapped() { + memset(overlapped(), 0, sizeof(OVERLAPPED)); +} + +void MemlogReceiverPipe::CompletionThunk::OnIOCompleted( + base::MessagePumpForIO::IOContext* context, + DWORD bytes_transfered, + DWORD error) { + // Note: any crashes with this on the stack are likely a result of destroying + // a relevant class while there is I/O pending. + callback_.Run(static_cast<size_t>(bytes_transfered), error); +} + +MemlogReceiverPipe::MemlogReceiverPipe(std::unique_ptr<CompletionThunk> thunk) + : thunk_(std::move(thunk)), read_buffer_(new char[kReadBufferSize]) { + // Need Unretained to avoid a reference cycle. + thunk_->set_callback(base::BindRepeating(&MemlogReceiverPipe::OnIOCompleted, + base::Unretained(this))); +} + +MemlogReceiverPipe::~MemlogReceiverPipe() {} + +void MemlogReceiverPipe::StartReadingOnIOThread() { + ReadUntilBlocking(); +} + +int MemlogReceiverPipe::GetRemoteProcessID() { + ULONG id = 0; + ::GetNamedPipeClientProcessId(thunk_->handle(), &id); + return static_cast<int>(id); +} + +void MemlogReceiverPipe::SetReceiver( + scoped_refptr<base::TaskRunner> task_runner, + scoped_refptr<MemlogStreamReceiver> receiver) { + receiver_task_runner_ = task_runner; + receiver_ = receiver; +} + +void MemlogReceiverPipe::OnIOCompleted(size_t bytes_transfered, DWORD error) { + DCHECK(read_outstanding_); + read_outstanding_ = false; + + // This will get called both for async completion of ConnectNamedPipe as well + // as async read completions. + if (bytes_transfered && receiver_) { + receiver_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MemlogStreamReceiver::OnStreamData, receiver_, + std::move(read_buffer_), bytes_transfered)); + read_buffer_.reset(new char[kReadBufferSize]); + } + ReadUntilBlocking(); +} + +void MemlogReceiverPipe::ReadUntilBlocking() { + // TODO(brettw) note that the IO completion callback will always be issued, + // even for sync returns of ReadFile. If there is a lot of data ready to be + // read, it would be nice to process them all in this loop rather than having + // to go back to the message loop for each block, but that will require + // different IOContext structures for each one. + DWORD bytes_read = 0; + thunk_->ZeroOverlapped(); + + DCHECK(!read_outstanding_); + read_outstanding_ = true; + if (!::ReadFile(thunk_->handle(), read_buffer_.get(), kReadBufferSize, + &bytes_read, thunk_->overlapped())) { + if (GetLastError() == ERROR_IO_PENDING) { + return; + } else { + if (receiver_) { + receiver_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MemlogStreamReceiver::OnStreamComplete, receiver_)); + } + return; + } + } +} + +} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe_win.h b/chrome/profiling/memlog_receiver_pipe_win.h new file mode 100644 index 0000000..a5b5392 --- /dev/null +++ b/chrome/profiling/memlog_receiver_pipe_win.h
@@ -0,0 +1,90 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_ +#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_ + +#include <windows.h> + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_pump_win.h" +#include "base/strings/string16.h" +#include "build/build_config.h" + +namespace base { +class TaskRunner; +} + +namespace profiling { + +class MemlogStreamReceiver; + +class MemlogReceiverPipe + : public base::RefCountedThreadSafe<MemlogReceiverPipe> { + public: + // RegisterIOHandler can't change the callback ID of a handle once it has + // been registered. This class allows switching the callbacks from the + // server to the pipe once the pipe is created while keeping the IOHandler + // attached to the handle the same. + class CompletionThunk : public base::MessagePumpForIO::IOHandler { + public: + using Callback = base::RepeatingCallback<void(size_t, DWORD)>; + + // Takes ownership of HANDLE and closes it when the class goes out of scope. + CompletionThunk(HANDLE handle, Callback cb); + ~CompletionThunk(); + + void set_callback(Callback cb) { callback_ = cb; } + + HANDLE handle() { return handle_; } + OVERLAPPED* overlapped() { return &context_.overlapped; } + + void ZeroOverlapped(); + + private: + // IOHandler implementation. + void OnIOCompleted(base::MessagePumpForIO::IOContext* context, + DWORD bytes_transfered, + DWORD error) override; + + base::MessagePumpForIO::IOContext context_; + + HANDLE handle_; + Callback callback_; + + DISALLOW_COPY_AND_ASSIGN(CompletionThunk); + }; + + explicit MemlogReceiverPipe(std::unique_ptr<CompletionThunk> thunk); + ~MemlogReceiverPipe(); + + void StartReadingOnIOThread(); + + int GetRemoteProcessID(); + void SetReceiver(scoped_refptr<base::TaskRunner> task_runner, + scoped_refptr<MemlogStreamReceiver> receiver); + + private: + void OnIOCompleted(size_t bytes_transfered, DWORD error); + + void ReadUntilBlocking(); + + std::unique_ptr<CompletionThunk> thunk_; + + scoped_refptr<base::TaskRunner> receiver_task_runner_; + scoped_refptr<MemlogStreamReceiver> receiver_; + + bool read_outstanding_ = false; + + std::unique_ptr<char[]> read_buffer_; + + DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipe); +}; + +} // namespace profiling + +#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_
diff --git a/chrome/profiling/memlog_stream_receiver.h b/chrome/profiling/memlog_stream_receiver.h new file mode 100644 index 0000000..ea8a6d6 --- /dev/null +++ b/chrome/profiling/memlog_stream_receiver.h
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_ +#define CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" + +namespace profiling { + +// A stream receiver is a sink for unparsed bytes. See also LogReceiver. +class MemlogStreamReceiver + : public base::RefCountedThreadSafe<MemlogStreamReceiver> { + public: + MemlogStreamReceiver() {} + virtual ~MemlogStreamReceiver() {} + + // Returns true on success, false on unrecoverable error (in which case no + // more blocks will be sent). May take a ref to the block, so the caller + // should not modify it later. + virtual void OnStreamData(std::unique_ptr<char[]> data, size_t sz) = 0; + + virtual void OnStreamComplete() = 0; +}; + +} // namespace profiling + +#endif // CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index b3f3954c..8223607 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -273,6 +273,10 @@ # TODO(gmanikpure): re-enable this test when we stop supporting # WebView on KitKat. 'ClickTest.testCanClickAnImageMapArea', + # The WebView shell that we test against (on Kitkat) does not yet + # support Network.getCookies DevTools command. + # TODO(gmanikpure): reenable when it does. + 'ObjectStateAssumptionsTest.testOptionsForUninitializedWebDriver', ] )
diff --git a/chrome/test/data/extensions/api_test/permissions/optional/background.js b/chrome/test/data/extensions/api_test/permissions/optional/background.js index 2bf1e17b..956b655 100644 --- a/chrome/test/data/extensions/api_test/permissions/optional/background.js +++ b/chrome/test/data/extensions/api_test/permissions/optional/background.js
@@ -196,9 +196,13 @@ })); assertTrue(typeof chrome.bookmarks == 'object' && chrome.bookmarks != null); - assertThrows( - chrome.bookmarks.getTree, [function(){}], - "'bookmarks' requires a different Feature that is not present."); + var nativeBindingsError = + "'bookmarks.getTree' is not available in this context."; + var jsBindingsError = + "'bookmarks' requires a different Feature that is not present."; + var regexp = + new RegExp(nativeBindingsError + '|' + jsBindingsError); + assertThrows(chrome.bookmarks.getTree, [function(){}], regexp); } )); }, @@ -295,9 +299,12 @@ function(permissions) { assertTrue(typeof chrome.bookmarks == 'object' && chrome.bookmarks != null); - assertThrows( - chrome.bookmarks.getTree, [function(){}], - "'bookmarks' requires a different Feature that is not present."); + var nativeBindingsError = + "'bookmarks.getTree' is not available in this context."; + var jsBindingsError = + "'bookmarks' requires a different Feature that is not present."; + var regexp = new RegExp(nativeBindingsError + '|' + jsBindingsError); + assertThrows(chrome.bookmarks.getTree, [function(){}], regexp); }); chrome.permissions.request(
diff --git a/chrome/test/data/webui/md_bookmarks/command_manager_test.js b/chrome/test/data/webui/md_bookmarks/command_manager_test.js index 641c11d4..eb844b9 100644 --- a/chrome/test/data/webui/md_bookmarks/command_manager_test.js +++ b/chrome/test/data/webui/md_bookmarks/command_manager_test.js
@@ -124,7 +124,7 @@ var undoModifier = cr.isMac ? 'meta' : 'ctrl'; var undoKey = 'z'; var redoModifier = cr.isMac ? ['meta', 'shift'] : 'ctrl' - var redoKey = cr.isMac ? 'z' : 'y'; + var redoKey = cr.isMac ? 'Z' : 'y'; MockInteractions.pressAndReleaseKeyOn( document.body, '', undoModifier, undoKey); @@ -171,6 +171,16 @@ assertFalse(lastCreate.incognito); }); + test('shift-enter does not trigger enter commands', function() { + // Enter by itself performs an edit (Mac) or open (non-Mac). Ensure that + // shift-enter doesn't trigger those commands. + store.data.selection.items = new Set(['13']); + store.notifyObservers(); + + MockInteractions.pressAndReleaseKeyOn(document.body, 13, 'shift', 'Enter'); + commandManager.assertLastCommand(Command.OPEN_NEW_WINDOW); + }); + test('cannot execute "Open in New Tab" on folders with no items', function() { var items = new Set(['2']); assertFalse(commandManager.canExecute(Command.OPEN_NEW_TAB, items));
diff --git a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js index 628007ed..8ac2961d 100644 --- a/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js +++ b/chrome/test/data/webui/md_bookmarks/md_bookmarks_focus_test.js
@@ -185,14 +185,14 @@ test('keyboard commands are passed to command manager', function() { var commandManager = new TestCommandManager(); document.body.appendChild(commandManager); - chrome.bookmarkManagerPrivate.removeTrees = function() {} + chrome.bookmarkManagerPrivate.removeTrees = function() {}; store.data.selection.items = new Set(['3', '4']); store.data.selectedFolder = '2'; store.notifyObservers(); getFolderNode('2').$.container.focus(); - keydown('2', 'delete'); + keydown('2', 'Delete'); commandManager.assertLastCommand(Command.DELETE, ['2']); });
diff --git a/chromeos/components/tether/wifi_hotspot_connector.cc b/chromeos/components/tether/wifi_hotspot_connector.cc index a981679..d67bb76 100644 --- a/chromeos/components/tether/wifi_hotspot_connector.cc +++ b/chromeos/components/tether/wifi_hotspot_connector.cc
@@ -52,13 +52,13 @@ network_state_handler_->DisassociateTetherNetworkStateFromWifiNetwork( tether_network_guid_); if (successful_disassociation) { - PA_LOG(INFO) << "Wifi network with ID " << wifi_network_guid_ - << " successfully disassociated from Tether network with ID " - << tether_network_guid_ << "."; + PA_LOG(INFO) << "Wi-Fi network (ID \"" << wifi_network_guid_ << "\") " + << "successfully disassociated from Tether network (ID " + << "\"" << tether_network_guid_ << "\")."; } else { - PA_LOG(INFO) << "Wifi network with ID " << wifi_network_guid_ - << " failed to disassociate from Tether network with ID " - << tether_network_guid_ << "."; + PA_LOG(INFO) << "Wi-Fi network (ID \"" << wifi_network_guid_ << "\") " + << "failed to disassociate from Tether network ID (\"" + << tether_network_guid_ << "\")."; } InvokeWifiConnectionCallback(std::string()); @@ -93,7 +93,13 @@ return; } - if (network->connectable()) { + if (network->connectable() && !has_initiated_connection_to_current_network_) { + // Set |has_initiated_connection_to_current_network_| to true to ensure that + // this code path is only run once per connection attempt. Without this + // field, the association and connection code below would be re-run multiple + // times for one network. + has_initiated_connection_to_current_network_ = true; + // If the network is now connectable, associate it with a Tether network // ASAP so that the correct icon will be displayed in the tray while the // network is connecting. @@ -101,17 +107,15 @@ network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork( tether_network_guid_, wifi_network_guid_); if (successful_association) { - PA_LOG(INFO) << "Wifi network with ID " << wifi_network_guid_ - << " is connectable, and successfully associated " - "with Tether network. Tether network ID: \"" - << tether_network_guid_ << "\", Wi-Fi network ID: \"" - << wifi_network_guid_ << "\""; + PA_LOG(INFO) << "Wi-Fi network (ID \"" << wifi_network_guid_ << "\") " + << "successfully associated with Tether network (ID \"" + << tether_network_guid_ << "\"). Starting connection " + << "attempt."; } else { - PA_LOG(INFO) << "Wifi network with ID " << wifi_network_guid_ - << " is connectable, but failed to associate tether network " - "with ID \"" - << tether_network_guid_ << "\" to Wi-Fi network with ID: \"" - << wifi_network_guid_ << "\""; + PA_LOG(INFO) << "Wi-Fi network (ID \"" << wifi_network_guid_ << "\") " + << "failed to associate with Tether network (ID \"" + << tether_network_guid_ << "\"). Starting connection " + << "attempt."; } // Initiate a connection to the network. @@ -130,6 +134,7 @@ ssid_.clear(); password_.clear(); wifi_network_guid_.clear(); + has_initiated_connection_to_current_network_ = false; timer_->Stop();
diff --git a/chromeos/components/tether/wifi_hotspot_connector.h b/chromeos/components/tether/wifi_hotspot_connector.h index eddc7ad..a947454 100644 --- a/chromeos/components/tether/wifi_hotspot_connector.h +++ b/chromeos/components/tether/wifi_hotspot_connector.h
@@ -70,6 +70,7 @@ std::string tether_network_guid_; std::string wifi_network_guid_; WifiConnectionCallback callback_; + bool has_initiated_connection_to_current_network_ = false; base::WeakPtrFactory<WifiHotspotConnector> weak_ptr_factory_;
diff --git a/chromeos/components/tether/wifi_hotspot_connector_unittest.cc b/chromeos/components/tether/wifi_hotspot_connector_unittest.cc index c3d3605..628d132 100644 --- a/chromeos/components/tether/wifi_hotspot_connector_unittest.cc +++ b/chromeos/components/tether/wifi_hotspot_connector_unittest.cc
@@ -7,7 +7,6 @@ #include <memory> #include <sstream> -#include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" @@ -69,6 +68,8 @@ std::string network_id_to_connect() { return network_id_to_connect_; } + uint32_t num_connection_attempts() { return num_connection_attempts_; } + // NetworkConnect: void DisconnectFromNetworkId(const std::string& network_id) override {} bool MaybeShowConfigureUI(const std::string& network_id, @@ -100,6 +101,7 @@ } void ConnectToNetworkId(const std::string& network_id) override { + num_connection_attempts_++; network_id_to_connect_ = network_id; } @@ -108,6 +110,7 @@ std::unique_ptr<base::DictionaryValue> last_configuration_; std::string last_service_path_created_; std::string network_id_to_connect_; + uint32_t num_connection_attempts_ = 0; }; WifiHotspotConnectorTest() {} @@ -217,8 +220,10 @@ return wifi_guid; } - void VerifyTetherAndWifiNetworkAssociation(const std::string& wifi_guid, - const std::string& tether_guid) { + void VerifyTetherAndWifiNetworkAssociation( + const std::string& wifi_guid, + const std::string& tether_guid, + uint32_t expected_num_connection_attempts) { const NetworkState* wifi_network_state = network_state_handler()->GetNetworkStateFromGuid(wifi_guid); ASSERT_TRUE(wifi_network_state); @@ -228,6 +233,9 @@ network_state_handler()->GetNetworkStateFromGuid(tether_guid); ASSERT_TRUE(tether_network_state); EXPECT_EQ(wifi_guid, tether_network_state->tether_guid()); + + EXPECT_EQ(expected_num_connection_attempts, + test_network_connect_->num_connection_attempts()); } void VerifyNetworkNotAssociated(const std::string& guid) { @@ -314,7 +322,8 @@ // Network becomes connectable. NotifyConnectable(test_network_connect_->last_service_path_created()); - VerifyTetherAndWifiNetworkAssociation(wifi_guid, kTetherNetworkGuid); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid, kTetherNetworkGuid, 1u /* expected_num_connection_attempts */); EXPECT_EQ(wifi_guid, test_network_connect_->network_id_to_connect()); // Network connection does not occur. @@ -338,7 +347,8 @@ // Network becomes connectable. NotifyConnectable(test_network_connect_->last_service_path_created()); - VerifyTetherAndWifiNetworkAssociation(wifi_guid, kTetherNetworkGuid); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid, kTetherNetworkGuid, 1u /* expected_num_connection_attempts */); EXPECT_EQ(wifi_guid, test_network_connect_->network_id_to_connect()); EXPECT_EQ(0u, connection_callback_responses_.size()); @@ -360,7 +370,8 @@ // Network becomes connectable. NotifyConnectable(test_network_connect_->last_service_path_created()); - VerifyTetherAndWifiNetworkAssociation(wifi_guid, kTetherNetworkGuid); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid, kTetherNetworkGuid, 1u /* expected_num_connection_attempts */); EXPECT_EQ(wifi_guid, test_network_connect_->network_id_to_connect()); EXPECT_EQ(0u, connection_callback_responses_.size()); @@ -413,7 +424,9 @@ // Second network becomes connectable. NotifyConnectable(service_path2); - VerifyTetherAndWifiNetworkAssociation(wifi_guid2, kTetherNetworkGuid2); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid2, kTetherNetworkGuid2, + 1u /* expected_num_connection_attempts */); EXPECT_EQ(wifi_guid2, test_network_connect_->network_id_to_connect()); EXPECT_EQ(1u, connection_callback_responses_.size()); @@ -439,7 +452,9 @@ // First network becomes connectable. NotifyConnectable(service_path1); - VerifyTetherAndWifiNetworkAssociation(wifi_guid1, kTetherNetworkGuid); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid1, kTetherNetworkGuid, + 1u /* expected_num_connection_attempts */); // After network becomes connectable, request a connection to second network. wifi_hotspot_connector_->ConnectToWifiHotspot( @@ -465,7 +480,9 @@ // Second network becomes connectable. NotifyConnectable(service_path2); - VerifyTetherAndWifiNetworkAssociation(wifi_guid2, kTetherNetworkGuid2); + VerifyTetherAndWifiNetworkAssociation( + wifi_guid2, kTetherNetworkGuid2, + 2u /* expected_num_connection_attempts */); EXPECT_EQ(wifi_guid2, test_network_connect_->network_id_to_connect()); EXPECT_EQ(1u, connection_callback_responses_.size());
diff --git a/components/chrome_apps/webstore_widget/app/main.html b/components/chrome_apps/webstore_widget/app/main.html index 36b65860..cb18c37 100644 --- a/components/chrome_apps/webstore_widget/app/main.html +++ b/components/chrome_apps/webstore_widget/app/main.html
@@ -5,7 +5,7 @@ -- found in the LICENSE file. --> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="chrome://resources/css/apps/topbutton_bar.css">
diff --git a/components/crash/core/browser/resources/crashes.html b/components/crash/core/browser/resources/crashes.html index 19ba4001..f6b80a7 100644 --- a/components/crash/core/browser/resources/crashes.html +++ b/components/crash/core/browser/resources/crashes.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> @@ -12,7 +12,7 @@ <script src="chrome://resources/js/ios/web_ui.js"></script> </if> - <title i18n-content="crashesTitle"></title> + <title>$i18n{crashesTitle}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/widgets.css"> <link rel="stylesheet" href="crashes.css"> @@ -23,19 +23,20 @@ <script src="chrome://crashes/crashes.js"></script> </head> <body> - <header><h1 i18n-content="crashesTitle"></h1></header> + <header><h1>$i18n{crashesTitle}</h1></header> <div id="crashUploadStatus" hidden> - <a is="action-link" role="button" id="uploadCrashes" - i18n-content="uploadCrashesLinkText"></a> + <a is="action-link" role="button" id="uploadCrashes"> + $i18n{uploadCrashesLinkText} + </a> </div> <div id="disabledMode" hidden> - <h2 i18n-content="disabledHeader"></h2> - <p i18n-values=".innerHTML:disabledMessage"></p> + <h2>$i18n{disabledHeader}</h2> + <p>$i18nRaw{disabledMessage}</p> </div> <div id="crashesInfo"> <h2 id="countBanner"></h2> <div id="crashList"></div> - <p id="noCrashes" i18n-content="noCrashesMessage" hidden></p> + <p id="noCrashes" hidden>$i18n{noCrashesMessage}</p> </div> <script src="chrome://resources/js/i18n_template.js"></script> <script src="chrome://resources/js/jstemplate_compiled.js"></script>
diff --git a/components/dom_distiller/webui/resources/about_dom_distiller.html b/components/dom_distiller/webui/resources/about_dom_distiller.html index 2a7c7de..91c4f49d 100644 --- a/components/dom_distiller/webui/resources/about_dom_distiller.html +++ b/components/dom_distiller/webui/resources/about_dom_distiller.html
@@ -7,7 +7,7 @@ <html> <head> <meta charset="utf-8"> - <title i18n-content="domDistillerTitle"></title> + <title>$i18n{domDistillerTitle}</title> <link rel="stylesheet" href="chrome://resources/css/chrome_shared.css"> <link rel="stylesheet" href="chrome://resources/css/overlay.css"> <link rel="stylesheet" href="about_dom_distiller.css"> @@ -26,21 +26,21 @@ <div id="mainContent"> <div id="list-section"> <header> - <h1 id="listTitle" i18n-content="domDistillerTitle"></h1> + <h1 id="listTitle">$i18n{domDistillerTitle}</h1> </header> <div id="add-entry"> - <label for="article_url" i18n-content="addArticleUrl"></label> + <label for="article_url">$i18n{addArticleUrl}</label> <input type="text" id="article_url" /> <br/> - <button id="addbutton" i18n-content="addArticleAddButtonLabel"></button> - <button id="viewbutton" i18n-content="viewUrlButtonLabel"></button> - <span id="add-entry-error" i18n-content="addArticleFailedLabel"></span> - <span id="view-url-error" i18n-content="viewUrlFailedLabel"></span> + <button id="addbutton">$i18n{addArticleAddButtonLabel}</button> + <button id="viewbutton">$i18n{viewUrlButtonLabel}</button> + <span id="add-entry-error">$i18n{addArticleFailedLabel}</span> + <span id="view-url-error">$i18n{viewUrlFailedLabel}</span> </div> <div id="update-list"> <form> - <button id="refreshbutton" i18n-content="refreshButtonLabel"></button> - <span id="entries-list-loading" i18n-content="loadingEntries"></span> + <button id="refreshbutton">$i18n{refreshButtonLabel}</button> + <span id="entries-list-loading">$i18n{loadingEntries}</span> </form> </div> <ul id="entries-list">
diff --git a/components/flags_ui/resources/apple_flags.html b/components/flags_ui/resources/apple_flags.html index 5b34466..3760509 100644 --- a/components/flags_ui/resources/apple_flags.html +++ b/components/flags_ui/resources/apple_flags.html
@@ -1,5 +1,5 @@ <!DOCTYPE HTML> -<html i18n-values="dir:textdirection;"> +<html dir="$i18n{textdirection}"> <head> <meta charset="utf-8"> <if expr="is_android or is_ios"> @@ -14,7 +14,7 @@ <script src="chrome://ui-alternatives/flags.js"></script> <script src="chrome://ui-alternatives/strings.js"></script> </head> -<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> +<body style="fontFamily:$i18n{fontfamily};fontSize:$i18n{fontsize}"> <div id="body-container" style="visibility:hidden"> <div id="flagsTemplate"> <div id="container" class="vbox-container"> @@ -22,11 +22,11 @@ <div class="section-header"> <table cellpadding="0" cellspacing="0"><tr valign="center"> <td> - <span class="section-header-title" i18n-content="flagsTableTitle" - >TITLE</span> + <span class="section-header-title">$i18n{flagsTableTitle}</span> <button id="experiment-reset-all" - jsdisplay="supportedFeatures.length > 0" type="button" - i18n-content="resetAllButton"></button> + jsdisplay="supportedFeatures.length > 0" type="button"> + $i18n{resetAllButton} + </button> </td> </tr></table> </div> @@ -36,11 +36,10 @@ <div class="content"> <div class="experiment-name no-experiments" jsdisplay="supportedFeatures.length == 0"> - <div i18n-content="flagsNoExperimentsAvailable" - >NO_EXPERIMENTS_ARE_AVAILABLE</div> + <div>$i18n{flagsNoExperimentsAvailable}</div> </div> - <div jsdisplay="supportedFeatures.length > 0"> + <div jsdisplay="supportedFeatures.length > 0"> <div class="experiment" jsselect="supportedFeatures" jsvalues="id:internal_name"> @@ -78,29 +77,22 @@ <a class="experiment-disable-link" jsvalues=".internal_name:internal_name" - jsdisplay="enabled" - href="#" - i18n-content="disable" - >DISABLE</a> + jsdisplay="enabled" href="#">$i18n{disable}</a> <a class="experiment-enable-link" jsvalues=".internal_name:internal_name" - jsdisplay="!enabled" - href="#" - i18n-content="enable" - >ENABLE</a> + jsdisplay="!enabled" href="#">$i18n{enable}</a> </span> </div> </td> </tr> </table> </div> - </div> + </div> </div> - <div class="needs-restart" - jsdisplay="supportedFeatures.length > 0"> - <div i18n-content="flagsRestartNotice">NEEDS_RESTART</div> + <div class="needs-restart" jsdisplay="supportedFeatures.length > 0"> + <div>$i18n{flagsRestartNotice}</div> </div> </div> </div>
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index aca6d35d..72a6ed3 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <if expr="is_android or is_ios"> @@ -22,19 +22,19 @@ <div id="body-container" style="visibility:hidden"> <div id="header"> - <div id="title-spacer"><h1 i18n-content="flagsLongTitle"></h1></div> + <div id="title-spacer"><h1>$i18n{flagsLongTitle}</h1></div> </div> <div class="blurb-container"> - <span id="blurb-warning" i18n-content="flagsWarningHeader">WARNING</span> - <span i18n-content="flagsBlurb">WARNING TEXT</span> - <span id="channel-promo-beta" i18n-content="channelPromoBeta" hidden></span> - <span id="channel-promo-dev" i18n-content="channelPromoDev" hidden></span> + <span id="blurb-warning">$i18n{flagsWarningHeader}</span> + <span>$i18n{flagsBlurb}</span> + <span id="channel-promo-beta" hidden>$i18n{channelPromoBeta}</span> + <span id="channel-promo-dev" hidden>$i18n{channelPromoDev}</span> </div> <if expr="chromeos"> <div class="blurb-container" id="owner-warning"> - <span i18n-content="ownerWarning"></span> + <span>$i18n{ownerWarning}</span> </div> </if> @@ -44,10 +44,10 @@ <div class="section-header"> <table cellpadding="0" cellspacing="0"><tr valign="center"> <td> - <span class="section-header-title" i18n-content="flagsTableTitle" - >TITLE</span> - <button id="experiment-reset-all" type="button" - i18n-content="resetAllButton"></button> + <span class="section-header-title">$i18n{flagsTableTitle}</span> + <button id="experiment-reset-all" type="button"> + $i18n{resetAllButton} + </button> </td> </tr></table> </div> @@ -92,17 +92,11 @@ <a class="experiment-disable-link" jsvalues=".internal_name:internal_name" - jsdisplay="enabled" - href="#" - i18n-content="disable" - >DISABLE</a> + jsdisplay="enabled" href="#">$i18n{disable}</a> <a class="experiment-enable-link" jsvalues=".internal_name:internal_name" - jsdisplay="!enabled" - href="#" - i18n-content="enable" - >ENABLE</a> + jsdisplay="!enabled" href="#">$i18n{enable}</a> </span> </div> </td> @@ -118,9 +112,8 @@ <div class="section-header"> <table cellpadding="0" cellspacing="0"><tr valign="center"> <td> - <span class="section-header-title" - i18n-content="flagsUnsupportedTableTitle" - >TITLE + <span class="section-header-title"> + $i18n{flagsUnsupportedTableTitle} </span> </td> </tr></table> @@ -149,7 +142,7 @@ </div> </div> <div class="experiment-actions"> - <div i18n-content="flagsNotSupported"></div> + <div>$i18n{flagsNotSupported}</div> </div> </td> </tr> @@ -159,9 +152,10 @@ </if> <div class="needs-restart" jsdisplay="needsRestart"> - <div i18n-content="flagsRestartNotice">NEEDS_RESTART</div> - <button class="experiment-restart-button" type="button" - i18n-content="flagsRestartButton">RESTART</button> + <div>$i18n{flagsRestartNotice}</div> + <button class="experiment-restart-button" type="button"> + $i18n{flagsRestartButton} + </button> </div> </div> </div>
diff --git a/components/gcm_driver/resources/gcm_internals.html b/components/gcm_driver/resources/gcm_internals.html index 67ec5981..70d497c 100644 --- a/components/gcm_driver/resources/gcm_internals.html +++ b/components/gcm_driver/resources/gcm_internals.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>GCM Internals</title>
diff --git a/components/neterror/resources/neterror.html b/components/neterror/resources/neterror.html index 3038e717..4c652ae 100644 --- a/components/neterror/resources/neterror.html +++ b/components/neterror/resources/neterror.html
@@ -1,10 +1,10 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - <title i18n-content="title"></title> + <title>$i18n{title}</title> <link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_common.css"> <link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_large.css"> <link rel="stylesheet" href="neterror.css"> @@ -12,7 +12,7 @@ <script src="neterror.js"></script> <script src="offline.js"></script> </head> -<body id="t" i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize"> +<body id="t" style="fontFamily:$i18n{fontfamily};fontSize:$i18n{fontsize}"> <div id="main-frame-error" class="interstitial-wrapper"> <div id="main-content"> <div class="icon"
diff --git a/components/physical_web/webui/resources/physical_web.html b/components/physical_web/webui/resources/physical_web.html index 034912e..a873271 100644 --- a/components/physical_web/webui/resources/physical_web.html +++ b/components/physical_web/webui/resources/physical_web.html
@@ -1,8 +1,8 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> -<title i18n-content="title"></title> +<title>$i18n{title}</title> <if expr="is_android or is_ios"> <meta name="viewport" content="width=device-width, user-scalable=no"> </if> @@ -22,9 +22,9 @@ <body> <div id="body-container" hidden> - <h1 i18n-content="title"></h1> + <h1>$i18n{title}</h1> <div id="render-container"></div> - <div id="empty-list-container" i18n-content="emptyMessage"></div> + <div id="empty-list-container">$i18n{emptyMessage}</div> </div> <a hidden id="render-template" class="physicalWebTemplate" jsselect="metadata"
diff --git a/components/signin/core/browser/resources/signin_index.html b/components/signin/core/browser/resources/signin_index.html index 7965ffe..513a934 100644 --- a/components/signin/core/browser/resources/signin_index.html +++ b/components/signin/core/browser/resources/signin_index.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <title>Signin Internals</title>
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html index 2a7de4b..04f411f 100644 --- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html +++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.html
@@ -1,10 +1,10 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, minimum-scale=1, width=device-width"> -<title i18n-content="blockPageTitle"></title> +<title>$i18n{blockPageTitle}</title> <link rel="stylesheet" href="supervised_user_block_interstitial.css"> <script src="../../../ui/webui/resources/js/cr.js"></script> <script src="../../../ui/webui/resources/js/util.js"></script> @@ -15,11 +15,10 @@ <div id="information-container"> <div class="icon" id="icon"></div> <div id="main-message"> - <h1 id="block-page-header" i18n-content="blockPageHeader"></h1> - <p id="block-page-message" i18n-content="blockPageMessage"></p> - <h1 id="request-failed-message" i18n-content="requestFailedMessage" - hidden></h1> - <h1 id="request-sent-message" i18n-content="requestSentMessage" hidden></h1> + <h1 id="block-page-header">$i18n{blockPageHeader}</h1> + <p id="block-page-message">$i18n{blockPageMessage}</p> + <h1 id="request-failed-message" hidden>$i18n{requestFailedMessage}</h1> + <h1 id="request-sent-message" hidden>$i18n{requestSentMessage}</h1> </div> <div id="custodians-information" hidden> <div id="custodian-information" class="custodian-information"> @@ -39,18 +38,25 @@ </div> </div> <div class="button-container"> - <button id="request-access-button" class="primary-button" i18n-content="requestAccessButton"> + <button id="request-access-button" class="primary-button"> + $i18n{requestAccessButton} </button> <div id="details-button-container"> - <button id="show-details-link" class="details-button small-link" i18n-content="showDetailsLink" hidden></button> - <button id="hide-details-link" class="details-button small-link" i18n-content="hideDetailsLink" hidden></button> - <button id="back-button" class="details-button small-link" i18n-content="backButton" hidden></button> + <button id="show-details-link" class="details-button small-link" hidden> + $i18n{showDetailsLink} + </button> + <button id="hide-details-link" class="details-button small-link" hidden> + $i18n{hideDetailsLink} + </button> + <button id="back-button" class="details-button small-link" hidden> + $i18n{backButton} + </button> </div> </div> <div id="details" hidden> - <p id="details-header" i18n-content="blockReasonHeader"></p> - <p id="details-message" i18n-content="blockReasonMessage"></p> - <p id="feedback" i18n-values=".innerHTML:feedbackLink"></p> + <p id="details-header">$i18n{blockReasonHeader}</p> + <p id="details-message">$i18n{blockReasonMessage}</p> + <p id="feedback">$i18nRaw{feedbackLink}</p> </div> </div> </body>
diff --git a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc index 7565ff4..41a6049 100644 --- a/components/supervised_user_error_page/supervised_user_error_page_unittest.cc +++ b/components/supervised_user_error_page/supervised_user_error_page_unittest.cc
@@ -76,14 +76,10 @@ param.profile_image_url2, param.custodian, param.custodian_email, param.second_custodian, param.second_custodian_email, param.is_child_account, param.reason, ""); - // The result should contain the original HTML plus scripts that plug values - // into it. The test can't easily check that the scripts are correct, but - // can check that the output contains the expected values. - std::string html = - ResourceBundle::GetSharedInstance() - .GetRawDataResource(IDR_SUPERVISED_USER_BLOCK_INTERSTITIAL_HTML) - .as_string(); - EXPECT_THAT(result, testing::HasSubstr(html)); + // The result should contain the original HTML (with $i18n{} replacements) + // plus scripts that plug values into it. The test can't easily check that the + // scripts are correct, but can check that the output contains the expected + // values. EXPECT_THAT(result, testing::HasSubstr(param.profile_image_url)); EXPECT_THAT(result, testing::HasSubstr(param.profile_image_url2)); EXPECT_THAT(result, testing::HasSubstr(param.custodian));
diff --git a/components/sync/driver/resources/index.html b/components/sync/driver/resources/index.html index 93d6b420..f37b632 100644 --- a/components/sync/driver/resources/index.html +++ b/components/sync/driver/resources/index.html
@@ -1,5 +1,5 @@ <!doctype html> -<html i18n-values="dir:textdirection;lang:language"> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <!-- If you change the title, make sure you also update chrome/test/functional/special_tabs.py. -->
diff --git a/components/version_ui/resources/about_version.html b/components/version_ui/resources/about_version.html index 19a261c..c19c5f8 100644 --- a/components/version_ui/resources/about_version.html +++ b/components/version_ui/resources/about_version.html
@@ -4,10 +4,10 @@ about:version template page --> -<html id="t" i18n-values="dir:textdirection;lang:language"> +<html id="t" dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> - <title i18n-content="title"></title> + <title>$i18n{title}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <if expr="is_android or is_ios"> <meta name="viewport" content="width=device-width"> @@ -40,66 +40,66 @@ <if expr="is_ios or is_android"> <img src="../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo.png"> </if> - <div id="company" i18n-content="company"></div> - <div id="copyright" i18n-content="copyright"></div> + <div id="company">$i18n{company}</div> + <div id="copyright">$i18n{copyright}</div> </div> <table id="inner" cellpadding="0" cellspacing="0" border="0"> - <tr><td class="label" i18n-content="application_label"></td> + <tr><td class="label">$i18n{application_label}</td> <td class="version" id="version"> - <span i18n-content="version"></span> - (<span i18n-content="official"></span>) - <span i18n-content="version_modifier"></span> - <span i18n-content="version_bitsize"></span> + <span>$i18n{version}</span> + (<span>$i18n{official}</span>) + <span>$i18n{version_modifier}</span> + <span>$i18n{version_bitsize}</span> <if expr="is_win"> - <span i18n-content="update_cohort_name"></span> + <span>$i18n{update_cohort_name}</span> </if> </td> </tr> <tr> - <td class="label" i18n-content="revision"></td> + <td class="label">$i18n{revision}</td> <td class="version"> - <span i18n-content="cl"></span> + <span>$i18n{cl}</span> </td> </tr> <if expr="not chromeos"> <tr> - <td class="label" i18n-content="os_name"></td> + <td class="label">$i18n{os_name}</td> <td class="version" id="os_type"> - <span i18n-content="os_type"></span> + <span>$i18n{os_type}</span> <if expr="is_android"> - <span i18n-content="os_version"></span> + <span>$i18n{os_version}</span> </if> </td> </tr> </if> <if expr="is_android"> <tr> - <td class="label" i18n-content="gms_name"></td> + <td class="label">$i18n{gms_name}</td> <td class="version" id="gms_version"> - <span i18n-content="gms_version"></span> + <span>$i18n{gms_version}</span> </td> </tr> </if> <if expr="chromeos"> <tr> - <td class="label" i18n-content="platform"></td> + <td class="label">$i18n{platform}</td> <td class="version" id="os_type"> <span id="os_version"></span> </td> </tr> <tr> - <td class="label" i18n-content="firmware_version"></td> + <td class="label">$i18n{firmware_version}</td> <td class="version"> <span id="firmware_version"></span> </td> </tr> <tr id="customization_id_holder" hidden> - <td class="label" i18n-content="customization_id"></td> + <td class="label">$i18n{customization_id}</td> <td class="version"> <span id="customization_id"></span> </td> </tr> - <tr id="arc_holder"><td class="label" i18n-content="arc_label"></td> + <tr id="arc_holder"><td class="label">$i18n{arc_label}</td> <td class="version"> <span id="arc_version"></span> </td> @@ -108,38 +108,38 @@ <if expr="not is_ios"> <tr><td class="label">JavaScript</td> <td class="version" id="js_engine"> - <span i18n-content="js_engine"></span> - <span i18n-content="js_version"></span> + <span>$i18n{js_engine}</span> + <span>$i18n{js_version}</span> </td> </tr> </if> <if expr="not is_android and not is_ios"> - <tr><td class="label" i18n-content="flash_plugin"></td> - <td class="version" id="flash_version" i18n-content="flash_version"></td> + <tr><td class="label">$i18n{flash_plugin}</td> + <td class="version" id="flash_version">$i18n{flash_version}</td> </tr> </if> - <tr><td class="label" i18n-content="user_agent_name"></td> - <td class="version" id="useragent" i18n-content="useragent"></td> + <tr><td class="label">$i18n{user_agent_name}</td> + <td class="version" id="useragent">$i18n{useragent}</td> </tr> - <tr><td class="label" i18n-content="command_line_name"></td> - <td class="version" id="command_line" i18n-content="command_line"></td> + <tr><td class="label">$i18n{command_line_name}</td> + <td class="version" id="command_line">$i18n{command_line}</td> </tr> <if expr="not is_ios"> - <tr><td class="label" i18n-content="executable_path_name"></td> - <td class="version" id="executable_path" i18n-content="executable_path"></td> + <tr><td class="label">$i18n{executable_path_name}</td> + <td class="version" id="executable_path">$i18n{executable_path}</td> </tr> - <tr><td class="label" i18n-content="profile_path_name"></td> - <td class="version" id="profile_path" i18n-content="profile_path"></td> + <tr><td class="label">$i18n{profile_path_name}</td> + <td class="version" id="profile_path">$i18n{profile_path}</td> </tr> </if> <tr id="variations-section"> - <td class="label" i18n-content="variations_name"></td> + <td class="label">$i18n{variations_name}</td> <td class="version" id="variations-list"></td> </tr> <if expr="is_win"> <tr id="compiler-section"> <td class="label">Compiler</td> - <td class="version" id="compiler" i18n-content="compiler"></td> + <td class="version" id="compiler">$i18n{compiler}</td> </tr> </if> </table>
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index 40037d2..af783af8 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -128,19 +128,24 @@ url_.possibly_invalid_spec()); DCHECK(!navigation_start.is_null()); - site_url_ = SiteInstance::GetSiteForURL( - frame_tree_node_->navigator()->GetController()->GetBrowserContext(), - url_); + site_url_ = SiteInstance::GetSiteForURL(frame_tree_node_->current_frame_host() + ->GetSiteInstance() + ->GetBrowserContext(), + url_); if (redirect_chain_.empty()) redirect_chain_.push_back(url); starting_site_instance_ = frame_tree_node_->current_frame_host()->GetSiteInstance(); - if (pending_nav_entry_id_) { - NavigationControllerImpl* nav_controller = - static_cast<NavigationControllerImpl*>( - frame_tree_node_->navigator()->GetController()); + // Try to match this with a pending NavigationEntry if possible. Note that + // the NavigationController itself may be gone if this is a navigation inside + // an interstitial and the interstitial is asynchronously deleting itself due + // to its tab closing. + NavigationControllerImpl* nav_controller = + static_cast<NavigationControllerImpl*>( + frame_tree_node_->navigator()->GetController()); + if (pending_nav_entry_id_ && nav_controller) { NavigationEntryImpl* nav_entry = nav_controller->GetEntryWithUniqueID(pending_nav_entry_id_); if (!nav_entry &&
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 436617f..5e4e948e 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -35,6 +35,7 @@ #include "content/public/browser/guest_mode.h" #include "content/public/browser/render_process_host.h" #include "gpu/ipc/common/gpu_messages.h" +#include "services/service_manager/runner/common/client_util.h" #include "third_party/WebKit/public/platform/WebTouchEvent.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_f.h" @@ -62,14 +63,18 @@ frame_connector_(nullptr), background_color_(SK_ColorWHITE), weak_factory_(this) { - GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); - CreateCompositorFrameSinkSupport(); + if (!service_manager::ServiceManagerIsRemote()) { + GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_); + CreateCompositorFrameSinkSupport(); + } } RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() { - ResetCompositorFrameSinkSupport(); - if (GetSurfaceManager()) - GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); + if (!service_manager::ServiceManagerIsRemote()) { + ResetCompositorFrameSinkSupport(); + if (GetSurfaceManager()) + GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); + } } void RenderWidgetHostViewChildFrame::Init() { @@ -99,7 +104,8 @@ return; if (frame_connector_) { - if (parent_frame_sink_id_.is_valid()) { + if (parent_frame_sink_id_.is_valid() && + !service_manager::ServiceManagerIsRemote()) { GetSurfaceManager()->UnregisterFrameSinkHierarchy(parent_frame_sink_id_, frame_sink_id_); } @@ -117,8 +123,10 @@ if (parent_view) { parent_frame_sink_id_ = parent_view->GetFrameSinkId(); DCHECK(parent_frame_sink_id_.is_valid()); - GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, - frame_sink_id_); + if (!service_manager::ServiceManagerIsRemote()) { + GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_, + frame_sink_id_); + } } auto* root_view = frame_connector_->GetRootRenderWidgetHostView(); @@ -442,6 +450,8 @@ } void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder() { + if (service_manager::ServiceManagerIsRemote()) + return; cc::SurfaceSequence sequence = cc::SurfaceSequence(frame_sink_id_, next_surface_sequence_++); cc::SurfaceManager* manager = GetSurfaceManager(); @@ -781,6 +791,9 @@ }; void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() { + if (service_manager::ServiceManagerIsRemote()) + return; + DCHECK(!support_); constexpr bool is_root = false; constexpr bool handles_frame_sink_id_invalidation = false;
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index ae9efdb..b2dcff2d 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -116,7 +116,8 @@ if (gesture_event.event.source_device == blink::kWebGestureDeviceTouchscreen) touchscreen_tap_suppression_controller_.GestureFlingCancel(); - else + else if (gesture_event.event.source_device == + blink::kWebGestureDeviceTouchpad) touchpad_tap_suppression_controller_.GestureFlingCancel(); return true; case WebInputEvent::kGestureTapDown: @@ -243,7 +244,8 @@ if (event_with_latency.event.source_device == blink::kWebGestureDeviceTouchscreen) touchscreen_tap_suppression_controller_.GestureFlingCancelAck(processed); - else + else if (event_with_latency.event.source_device == + blink::kWebGestureDeviceTouchpad) touchpad_tap_suppression_controller_.GestureFlingCancelAck(processed); } DCHECK_LT(event_index, coalesced_gesture_events_.size());
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 9ca4cf6..b7518d4 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -91,6 +91,7 @@ #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/vector2d_conversions.h" +#include "ui/gfx/geometry/vector2d_f.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/skbitmap_operations.h" @@ -558,6 +559,9 @@ IPC_MESSAGE_HANDLER(ViewHostMsg_DidNotProduceFrame, DidNotProduceFrame) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor) + IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollStart, OnAutoscrollStart) + IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollFling, OnAutoscrollFling) + IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollEnd, OnAutoscrollEnd) IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, OnTextInputStateChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse) @@ -2031,6 +2035,42 @@ SetCursor(cursor); } +void RenderWidgetHostImpl::OnAutoscrollStart(const gfx::PointF& position) { + WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build( + WebInputEvent::kGestureScrollBegin, + blink::kWebGestureDeviceSyntheticAutoscroll); + + scroll_begin.x = position.x(); + scroll_begin.y = position.y(); + scroll_begin.source_device = blink::kWebGestureDeviceSyntheticAutoscroll; + + input_router_->SendGestureEvent(GestureEventWithLatencyInfo(scroll_begin)); +} + +void RenderWidgetHostImpl::OnAutoscrollFling(const gfx::Vector2dF& velocity) { + WebGestureEvent event = SyntheticWebGestureEventBuilder::Build( + WebInputEvent::kGestureFlingStart, + blink::kWebGestureDeviceSyntheticAutoscroll); + event.data.fling_start.velocity_x = velocity.x(); + event.data.fling_start.velocity_y = velocity.y(); + event.source_device = blink::kWebGestureDeviceSyntheticAutoscroll; + + input_router_->SendGestureEvent(GestureEventWithLatencyInfo(event)); +} + +void RenderWidgetHostImpl::OnAutoscrollEnd() { + WebGestureEvent cancel_event = SyntheticWebGestureEventBuilder::Build( + WebInputEvent::kGestureFlingCancel, + blink::kWebGestureDeviceSyntheticAutoscroll); + cancel_event.data.fling_cancel.prevent_boosting = true; + input_router_->SendGestureEvent(GestureEventWithLatencyInfo(cancel_event)); + + WebGestureEvent end_event = SyntheticWebGestureEventBuilder::Build( + WebInputEvent::kGestureScrollEnd, + blink::kWebGestureDeviceSyntheticAutoscroll); + input_router_->SendGestureEvent(GestureEventWithLatencyInfo(end_event)); +} + void RenderWidgetHostImpl::SetTouchEventEmulationEnabled( bool enabled, ui::GestureProviderConfigType config_type) { if (enabled) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 79210c2..f5baa73 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -77,6 +77,7 @@ namespace gfx { class Image; class Range; +class Vector2dF; } namespace content { @@ -658,6 +659,9 @@ void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params); void OnQueueSyntheticGesture(const SyntheticGesturePacket& gesture_packet); void OnSetCursor(const WebCursor& cursor); + void OnAutoscrollStart(const gfx::PointF& position); + void OnAutoscrollFling(const gfx::Vector2dF& velocity); + void OnAutoscrollEnd(); void OnTextInputStateChanged(const TextInputState& params); void OnImeCompositionRangeChanged(
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index b859ecb..afcdaf9 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2189,8 +2189,8 @@ new TestInterstitialPage(contents(), true, url2, &state, &deleted); TestInterstitialPageStateGuard state_guard(interstitial); interstitial->Show(); - RenderFrameHostImpl* interstitial_rfh = - static_cast<RenderFrameHostImpl*>(interstitial->GetMainFrame()); + TestRenderFrameHost* interstitial_rfh = + static_cast<TestRenderFrameHost*>(interstitial->GetMainFrame()); // The interstitial should not show until its navigation has committed. EXPECT_FALSE(interstitial->is_showing()); EXPECT_FALSE(contents()->ShowingInterstitialPage()); @@ -2208,6 +2208,9 @@ interstitial_rfh, url2, std::vector<GURL>(), base::TimeTicks::Now()); EXPECT_FALSE(deleted); + // Simulate a commit in the interstitial page, which should also not crash. + interstitial_rfh->SimulateNavigationCommit(url2); + RunAllPendingInMessageLoop(); EXPECT_TRUE(deleted); }
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 0a67b02..b07a8370 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -679,6 +679,14 @@ IPC_MESSAGE_ROUTED1(ViewHostMsg_SetCursor, content::WebCursor) +// Request a non-decelerating synthetic fling animation to be latched on the +// scroller at the start point, and whose velocity can be changed over time by +// sending multiple AutoscrollFling gestures. Used for features like +// middle-click autoscroll. +IPC_MESSAGE_ROUTED1(ViewHostMsg_AutoscrollStart, gfx::PointF /* start */) +IPC_MESSAGE_ROUTED1(ViewHostMsg_AutoscrollFling, gfx::Vector2dF /* velocity */) +IPC_MESSAGE_ROUTED0(ViewHostMsg_AutoscrollEnd) + // Get the list of proxies to use for |url|, as a semicolon delimited list // of "<TYPE> <HOST>:<PORT>" | "DIRECT". IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_ResolveProxy,
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 6873af8..0129dad 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -186,6 +186,12 @@ SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + + // COM is used by some Windows Media Foundation calls made on this thread and + // must be MTA so we don't have to worry about pumping messages to handle + // COM callbacks. + base::win::ScopedCOMInitializer com_initializer( + base::win::ScopedCOMInitializer::kMTA); #endif logging::SetLogMessageHandler(GpuProcessLogMessageHandler); @@ -203,8 +209,8 @@ new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT)); } else { #if defined(OS_WIN) - // OK to use default non-UI message loop because all GPU windows run on - // dedicated thread. + // The GpuMain thread should not be pumping Windows messages because no UI + // is expected to run on this thread. main_message_loop.reset( new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT)); #elif defined(USE_X11)
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 7a3e95dc..0cc1871 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1430,6 +1430,18 @@ } } +void RenderWidget::AutoscrollStart(const blink::WebFloatPoint& point) { + Send(new ViewHostMsg_AutoscrollStart(routing_id_, point)); +} + +void RenderWidget::AutoscrollFling(const blink::WebFloatSize& velocity) { + Send(new ViewHostMsg_AutoscrollFling(routing_id_, velocity)); +} + +void RenderWidget::AutoscrollEnd() { + Send(new ViewHostMsg_AutoscrollEnd(routing_id_)); +} + // We are supposed to get a single call to Show for a newly created RenderWidget // that was created via RenderWidget::CreateWebView. So, we wait until this // point to dispatch the ShowWidget message.
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 2b2ca4c..ac63c77 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -284,6 +284,9 @@ blink::WebLayerTreeView* InitializeLayerTreeView() override; void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override; void DidChangeCursor(const blink::WebCursorInfo&) override; + void AutoscrollStart(const blink::WebFloatPoint& point) override; + void AutoscrollFling(const blink::WebFloatSize& velocity) override; + void AutoscrollEnd() override; void CloseWidgetSoon() override; void Show(blink::WebNavigationPolicy) override; blink::WebRect WindowRect() override;
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index 210ff48..48eaf4ea 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -126,6 +126,7 @@ public_deps = [ "//gpu/ipc/common:interfaces", "//mojo/common:common_custom_types", + "//ui/gfx/geometry/mojo", ] # TODO(crbug.com/699569): Convert to use the new JS bindings.
diff --git a/device/vr/android/gvr/gvr_delegate.cc b/device/vr/android/gvr/gvr_delegate.cc index f4d94e8..60d0bb0 100644 --- a/device/vr/android/gvr/gvr_delegate.cc +++ b/device/vr/android/gvr/gvr_delegate.cc
@@ -211,6 +211,16 @@ } /* static */ +mojom::VRDisplayInfoPtr GvrDelegate::CreateDefaultVRDisplayInfo( + gvr::GvrApi* gvr_api, + uint32_t device_id) { + if (!gvr_api) + return nullptr; + return CreateVRDisplayInfo(gvr_api, GetRecommendedWebVrSize(gvr_api), + device_id); +} + +/* static */ mojom::VRDisplayInfoPtr GvrDelegate::CreateVRDisplayInfo( gvr::GvrApi* gvr_api, gfx::Size recommended_size,
diff --git a/device/vr/android/gvr/gvr_delegate.h b/device/vr/android/gvr/gvr_delegate.h index e3c6efb..d9562c52 100644 --- a/device/vr/android/gvr/gvr_delegate.h +++ b/device/vr/android/gvr/gvr_delegate.h
@@ -14,7 +14,6 @@ #include "ui/gfx/geometry/size.h" namespace gfx { -class RectF; class Transform; } // namespace gfx @@ -40,36 +39,27 @@ gvr::GvrApi* gvr_api, gfx::Transform* head_mat_out); static gfx::Size GetRecommendedWebVrSize(gvr::GvrApi* gvr_api); + static mojom::VRDisplayInfoPtr CreateDefaultVRDisplayInfo( + gvr::GvrApi* gvr_api, + uint32_t device_id); static mojom::VRDisplayInfoPtr CreateVRDisplayInfo(gvr::GvrApi* gvr_api, gfx::Size recommended_size, uint32_t device_id); virtual void SetWebVRSecureOrigin(bool secure_origin) = 0; - virtual void SubmitWebVRFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) = 0; - virtual void UpdateWebVRTextureBounds(int16_t frame_index, - const gfx::RectF& left_bounds, - const gfx::RectF& right_bounds, - const gfx::Size& source_size) = 0; - virtual void OnVRVsyncProviderRequest( - mojom::VRVSyncProviderRequest request) = 0; virtual void UpdateVSyncInterval(int64_t timebase_nanos, double interval_seconds) = 0; virtual void CreateVRDisplayInfo( const base::Callback<void(mojom::VRDisplayInfoPtr)>& callback, uint32_t device_id) = 0; + virtual void ConnectPresentingService( + device::mojom::VRSubmitFrameClientPtr submit_client, + device::mojom::VRPresentationProviderRequest request) = 0; protected: virtual ~GvrDelegate() {} }; -// GvrDelegate, which allows WebVR presentation. -class DEVICE_VR_EXPORT PresentingGvrDelegate : public GvrDelegate { - public: - virtual void SetSubmitClient( - device::mojom::VRSubmitFrameClientPtr submit_client) = 0; -}; - } // namespace device #endif // DEVICE_VR_ANDROID_GVR_DELEGATE_H
diff --git a/device/vr/android/gvr/gvr_delegate_provider.h b/device/vr/android/gvr/gvr_delegate_provider.h index 3bd4013..a35461a8 100644 --- a/device/vr/android/gvr/gvr_delegate_provider.h +++ b/device/vr/android/gvr/gvr_delegate_provider.h
@@ -24,10 +24,16 @@ virtual void ClearDeviceProvider() = 0; virtual void RequestWebVRPresent( mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) = 0; virtual void ExitWebVRPresent() = 0; virtual GvrDelegate* GetDelegate() = 0; virtual void SetListeningForActivate(bool listening) = 0; + virtual void CreateVRDisplayInfo( + const base::Callback<void(mojom::VRDisplayInfoPtr)>& callback, + uint32_t device_id) = 0; + virtual void GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) = 0; protected: virtual ~GvrDelegateProvider() {}
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc index 01584131..4a0a3aa 100644 --- a/device/vr/android/gvr/gvr_device.cc +++ b/device/vr/android/gvr/gvr_device.cc
@@ -26,15 +26,16 @@ void GvrDevice::CreateVRDisplayInfo( const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) { - GvrDelegate* delegate = GetGvrDelegate(); - if (delegate) { - delegate->CreateVRDisplayInfo(on_created, id()); + GvrDelegateProvider* delegate_provider = gvr_provider_->GetDelegateProvider(); + if (delegate_provider) { + delegate_provider->CreateVRDisplayInfo(on_created, id()); } else { on_created.Run(nullptr); } } void GvrDevice::RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) { GvrDelegateProvider* delegate_provider = gvr_provider_->GetDelegateProvider(); if (!delegate_provider) @@ -42,7 +43,8 @@ // RequestWebVRPresent is async as we may trigger a DON flow that pauses // Chrome. - delegate_provider->RequestWebVRPresent(std::move(submit_client), callback); + delegate_provider->RequestWebVRPresent(std::move(submit_client), + std::move(request), callback); } void GvrDevice::SetSecureOrigin(bool secure_origin) { @@ -59,36 +61,14 @@ OnExitPresent(); } -void GvrDevice::SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) { - GvrDelegate* delegate = GetGvrDelegate(); - if (delegate) { - delegate->SubmitWebVRFrame(frame_index, mailbox); - } -} - -void GvrDevice::UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds_ptr, - mojom::VRLayerBoundsPtr right_bounds_ptr, - int16_t source_width, - int16_t source_height) { - GvrDelegate* delegate = GetGvrDelegate(); - if (!delegate) +void GvrDevice::GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) { + GvrDelegateProvider* delegate_provider = gvr_provider_->GetDelegateProvider(); + if (!delegate_provider) { + std::move(callback).Run(nullptr); return; - - gfx::RectF left_bounds(left_bounds_ptr->left, left_bounds_ptr->top, - left_bounds_ptr->width, left_bounds_ptr->height); - gfx::RectF right_bounds(right_bounds_ptr->left, right_bounds_ptr->top, - right_bounds_ptr->width, right_bounds_ptr->height); - gfx::Size source_size(source_width, source_height); - delegate->UpdateWebVRTextureBounds(frame_index, left_bounds, right_bounds, - source_size); -} - -void GvrDevice::GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) { - GvrDelegate* delegate = GetGvrDelegate(); - if (delegate) - delegate->OnVRVsyncProviderRequest(std::move(request)); + } + delegate_provider->GetNextMagicWindowPose(std::move(callback)); } void GvrDevice::OnDelegateChanged() {
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h index 3564169e..945661c 100644 --- a/device/vr/android/gvr/gvr_device.h +++ b/device/vr/android/gvr/gvr_device.h
@@ -23,18 +23,13 @@ const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) override; void RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) override; void SetSecureOrigin(bool secure_origin) override; void ExitPresent() override; + void GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) override; - void SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override; - void UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds_ptr, - mojom::VRLayerBoundsPtr right_bounds_ptr, - int16_t source_width, - int16_t source_height) override; - void GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) override; void OnDelegateChanged(); private:
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 57cb475..185f068 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -3,18 +3,23 @@ // found in the LICENSE file. #define _USE_MATH_DEFINES // for M_PI -#include "device/vr/openvr/openvr_device.h" + #include <math.h> + +#include "base/memory/ptr_util.h" +#include "device/vr/openvr/openvr_device.h" #include "third_party/openvr/src/headers/openvr.h" +namespace device { + namespace { constexpr float kRadToDeg = static_cast<float>(180 / M_PI); constexpr float kDefaultIPD = 0.06f; // Default average IPD -device::mojom::VRFieldOfViewPtr openVRFovToWebVRFov(vr::IVRSystem* vr_system, - vr::Hmd_Eye eye) { - device::mojom::VRFieldOfViewPtr out = device::mojom::VRFieldOfView::New(); +mojom::VRFieldOfViewPtr OpenVRFovToWebVRFov(vr::IVRSystem* vr_system, + vr::Hmd_Eye eye) { + auto out = mojom::VRFieldOfView::New(); float up_tan, down_tan, left_tan, right_tan; vr_system->GetProjectionRaw(eye, &left_tan, &right_tan, &up_tan, &down_tan); out->upDegrees = -(atanf(up_tan) * kRadToDeg); @@ -72,9 +77,39 @@ return transform; } -} // namespace +class OpenVRRenderLoop : public base::SimpleThread, + mojom::VRPresentationProvider { + public: + OpenVRRenderLoop(vr::IVRSystem* vr); -namespace device { + void RegisterPollingEventCallback( + const base::Callback<void()>& on_polling_events); + + void UnregisterPollingEventCallback(); + + void Bind(mojom::VRPresentationProvider request); + + mojom::VRPosePtr GetPose(); + + private: + void Run() override; + + void GetVSync( + mojom::VRPresentationProvider::GetVSyncCallback callback) override; + void SubmitFrame(int16_t frame_index, + const gpu::MailboxHolder& mailbox) override; + void UpdateLayerBounds(int16_t frame_id, + const gfx::RectF& left_bounds, + const gfx::RectF& right_bounds, + const gfx::Size& source_size) override; + + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + base::Callback<void()> on_polling_events_; + vr::IVRSystem* vr_system_; + mojo::Binding<mojom::VRPresentationProvider> binding_; +}; + +} // namespace OpenVRDevice::OpenVRDevice(vr::IVRSystem* vr) : vr_system_(vr), weak_ptr_factory_(this), is_polling_events_(false) {} @@ -102,8 +137,8 @@ mojom::VREyeParametersPtr& left_eye = device->leftEye; mojom::VREyeParametersPtr& right_eye = device->rightEye; - left_eye->fieldOfView = openVRFovToWebVRFov(vr_system_, vr::Eye_Left); - right_eye->fieldOfView = openVRFovToWebVRFov(vr_system_, vr::Eye_Left); + left_eye->fieldOfView = OpenVRFovToWebVRFov(vr_system_, vr::Eye_Left); + right_eye->fieldOfView = OpenVRFovToWebVRFov(vr_system_, vr::Eye_Left); vr::TrackedPropertyError error = vr::TrackedProp_Success; float ipd = vr_system_->GetFloatTrackedDeviceProperty( @@ -146,7 +181,7 @@ // If it is the first initialization, OpenVRRenderLoop instance needs to be // created and the polling event callback needs to be registered. if (!render_loop_) { - render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system_); + render_loop_ = base::MakeUnique<OpenVRRenderLoop>(vr_system_); render_loop_->RegisterPollingEventCallback(base::Bind( &OpenVRDevice::OnPollingEvents, weak_ptr_factory_.GetWeakPtr())); @@ -156,6 +191,7 @@ } void OpenVRDevice::RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) { callback.Run(false); // We don't support presentation currently. @@ -169,24 +205,12 @@ // We don't support presentation currently, so don't do anything. } -void OpenVRDevice::SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) { - // We don't support presentation currently, so don't do anything. +void OpenVRDevice::GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) { + std::move(callback).Run(nullptr); } -void OpenVRDevice::UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds, - mojom::VRLayerBoundsPtr right_bounds, - int16_t source_width, - int16_t source_height) { - // We don't support presentation currently, so don't do anything. -} - -void OpenVRDevice::GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) { - render_loop_->Bind(std::move(request)); -} - -OpenVRDevice::OpenVRRenderLoop::OpenVRRenderLoop(vr::IVRSystem* vr_system) +OpenVRRenderLoop::OpenVRRenderLoop(vr::IVRSystem* vr_system) : vr_system_(vr_system), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), binding_(this), @@ -194,19 +218,18 @@ DCHECK(main_thread_task_runner_); } -void OpenVRDevice::OpenVRRenderLoop::Bind( - mojom::VRVSyncProviderRequest request) { +void OpenVRRenderLoop::Bind(mojom::VRPresentationProvider request) { binding_.Close(); binding_.Bind(std::move(request)); } -void OpenVRDevice::OpenVRRenderLoop::Run() { +void OpenVRRenderLoop::Run() { // TODO (BillOrr): We will wait for VSyncs on this thread using WaitGetPoses // when we support presentation. } -device::mojom::VRPosePtr OpenVRDevice::OpenVRRenderLoop::getPose() { - device::mojom::VRPosePtr pose = device::mojom::VRPose::New(); +mojom::VRPosePtr OpenVRRenderLoop::GetPose() { + mojom::VRPosePtr pose = mojom::VRPose::New(); pose->orientation.emplace(4); pose->orientation.value()[0] = 0; @@ -283,20 +306,20 @@ } // Register a callback function to deal with system events. -void OpenVRDevice::OpenVRRenderLoop::RegisterPollingEventCallback( - const base::Callback<void()>& onPollingEvents) { - if (onPollingEvents.is_null()) +void OpenVRRenderLoop::RegisterPollingEventCallback( + const base::Callback<void()>& on_polling_events) { + if (on_polling_events.is_null()) return; - on_polling_events_ = onPollingEvents; + on_polling_events_ = on_polling_events; } -void OpenVRDevice::OpenVRRenderLoop::UnregisterPollingEventCallback() { +void OpenVRRenderLoop::UnregisterPollingEventCallback() { on_polling_events_.Reset(); } -void OpenVRDevice::OpenVRRenderLoop::GetVSync( - mojom::VRVSyncProvider::GetVSyncCallback callback) { +void OpenVRRenderLoop::GetVSync( + mojom::VRPresentationProvider::GetVSyncCallback callback) { static int16_t next_frame = 0; int16_t frame = next_frame++; @@ -310,11 +333,23 @@ // since we don't have VSync hooked up. base::TimeDelta time = base::TimeDelta::FromSecondsD(2.0); - device::mojom::VRPosePtr pose = getPose(); + mojom::VRPosePtr pose = GetPose(); Sleep(11); // TODO (billorr): Use real vsync timing instead of a sleep (this // sleep just throttles vsyncs so we don't fill message queues). std::move(callback).Run(std::move(pose), time, frame, - device::mojom::VRVSyncProvider::Status::SUCCESS); + mojom::VRPresentationProvider::VSyncStatus::SUCCESS); } -} // namespace device \ No newline at end of file +void OpenVRRenderLoop::SubmitFrame(int16_t frame_index, + const gpu::MailboxHolder& mailbox) { + // We don't support presentation currently, so don't do anything. +} + +void OpenVRRenderLoop::UpdateLayerBounds(int16_t frame_id, + const gfx::RectF& left_bounds, + const gfx::RectF& right_bounds, + const gfx::Size& source_size) { + // We don't support presentation currently, so don't do anything. +} + +} // namespace device
diff --git a/device/vr/openvr/openvr_device.h b/device/vr/openvr/openvr_device.h index 2a136d23..1c5ed71 100644 --- a/device/vr/openvr/openvr_device.h +++ b/device/vr/openvr/openvr_device.h
@@ -5,9 +5,12 @@ #ifndef DEVICE_VR_OPENVR_DEVICE_H #define DEVICE_VR_OPENVR_DEVICE_H +#include <memory> + #include "base/macros.h" #include "base/threading/simple_thread.h" #include "device/vr/vr_device.h" +#include "device/vr/vr_service.mojom.h" #include "mojo/public/cpp/bindings/binding.h" namespace vr { @@ -16,6 +19,8 @@ namespace device { +class OpenVRRenderLoop; + class OpenVRDevice : public VRDevice { public: OpenVRDevice(vr::IVRSystem* vr); @@ -26,53 +31,20 @@ const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) override; void RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) override; void SetSecureOrigin(bool secure_origin) override; void ExitPresent() override; - - void SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override; - void UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds, - mojom::VRLayerBoundsPtr right_bounds, - int16_t source_width, - int16_t source_height) override; - void GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) override; + void GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) override; void OnPollingEvents(); private: - class OpenVRRenderLoop : public base::SimpleThread, - device::mojom::VRVSyncProvider { - public: - OpenVRRenderLoop(vr::IVRSystem* vr); - - void RegisterPollingEventCallback( - const base::Callback<void()>& onPollingEvents); - - void UnregisterPollingEventCallback(); - - void Bind(mojom::VRVSyncProviderRequest request); - - mojom::VRPosePtr getPose(); - - private: - void Run() override; - - void GetVSync( - device::mojom::VRVSyncProvider::GetVSyncCallback callback) override; - - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; - base::Callback<void()> on_polling_events_; - vr::IVRSystem* vr_system_; - mojo::Binding<device::mojom::VRVSyncProvider> binding_; - }; - - std::unique_ptr<OpenVRRenderLoop> - render_loop_; // TODO (BillOrr): This should not be a unique_ptr because - // the render_loop_ binds to VRVSyncProvider requests, - // so its lifetime should be tied to the lifetime of that - // binding. + // TODO (BillOrr): This should not be a unique_ptr because the render_loop_ + // binds to VRVSyncProvider requests, so its lifetime should be tied to the + // lifetime of that binding. + std::unique_ptr<OpenVRRenderLoop> render_loop_; mojom::VRSubmitFrameClientPtr submit_client_; @@ -87,4 +59,4 @@ } // namespace device -#endif // DEVICE_VR_OPENVR_DEVICE_H \ No newline at end of file +#endif // DEVICE_VR_OPENVR_DEVICE_H
diff --git a/device/vr/test/fake_vr_device.cc b/device/vr/test/fake_vr_device.cc index 01b6c1d..f5872f4 100644 --- a/device/vr/test/fake_vr_device.cc +++ b/device/vr/test/fake_vr_device.cc
@@ -60,6 +60,7 @@ } void FakeVRDevice::RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) { callback.Run(true); } @@ -70,15 +71,9 @@ OnExitPresent(); } -void FakeVRDevice::SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) {} - -void FakeVRDevice::UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr leftBounds, - mojom::VRLayerBoundsPtr rightBounds, - int16_t source_width, - int16_t source_height) {} - -void FakeVRDevice::GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) {} +void FakeVRDevice::GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) { + std::move(callback).Run(nullptr); +} } // namespace device
diff --git a/device/vr/test/fake_vr_device.h b/device/vr/test/fake_vr_device.h index 5c756805..c43e553 100644 --- a/device/vr/test/fake_vr_device.h +++ b/device/vr/test/fake_vr_device.h
@@ -27,17 +27,12 @@ const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) override; void RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) override; void SetSecureOrigin(bool secure_origin) override; void ExitPresent() override; - void SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override; - void UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr leftBounds, - mojom::VRLayerBoundsPtr rightBounds, - int16_t source_width, - int16_t source_height) override; - void GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) override; + void GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) override; private: mojom::VREyeParametersPtr InitEye(float fov, float offset, uint32_t size);
diff --git a/device/vr/vr_device.h b/device/vr/vr_device.h index ff1b898e..9b75194c 100644 --- a/device/vr/vr_device.h +++ b/device/vr/vr_device.h
@@ -32,17 +32,12 @@ const base::Callback<void(mojom::VRDisplayInfoPtr)>& on_created) = 0; virtual void RequestPresent(mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, const base::Callback<void(bool)>& callback) = 0; virtual void SetSecureOrigin(bool secure_origin) = 0; virtual void ExitPresent() = 0; - virtual void SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) = 0; - virtual void UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds, - mojom::VRLayerBoundsPtr right_bounds, - int16_t source_width, - int16_t source_height) = 0; - virtual void GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) = 0; + virtual void GetNextMagicWindowPose( + mojom::VRDisplay::GetNextMagicWindowPoseCallback callback) = 0; virtual void AddDisplay(VRDisplayImpl* display); virtual void RemoveDisplay(VRDisplayImpl* display);
diff --git a/device/vr/vr_display_impl.cc b/device/vr/vr_display_impl.cc index 1f164a1..b4c12d5f 100644 --- a/device/vr/vr_display_impl.cc +++ b/device/vr/vr_display_impl.cc
@@ -60,13 +60,14 @@ void VRDisplayImpl::RequestPresent(bool secure_origin, mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, RequestPresentCallback callback) { if (!device_->IsAccessAllowed(this)) { std::move(callback).Run(false); return; } - device_->RequestPresent(std::move(submit_client), + device_->RequestPresent(std::move(submit_client), std::move(request), base::Bind(&VRDisplayImpl::RequestPresentResult, weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback), secure_origin)); @@ -87,31 +88,13 @@ device_->ExitPresent(); } -void VRDisplayImpl::SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) { - if (!device_->CheckPresentingDisplay(this)) - return; - device_->SubmitFrame(frame_index, mailbox); -} - -void VRDisplayImpl::UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds, - mojom::VRLayerBoundsPtr right_bounds, - int16_t source_width, - int16_t source_height) { - if (!device_->IsAccessAllowed(this)) - return; - - device_->UpdateLayerBounds(frame_index, std::move(left_bounds), - std::move(right_bounds), source_width, - source_height); -} - -void VRDisplayImpl::GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) { +void VRDisplayImpl::GetNextMagicWindowPose( + GetNextMagicWindowPoseCallback callback) { if (!device_->IsAccessAllowed(this)) { + std::move(callback).Run(nullptr); return; } - device_->GetVRVSyncProvider(std::move(request)); + device_->GetNextMagicWindowPose(std::move(callback)); } } // namespace device
diff --git a/device/vr/vr_display_impl.h b/device/vr/vr_display_impl.h index e8c93170..1d7598a 100644 --- a/device/vr/vr_display_impl.h +++ b/device/vr/vr_display_impl.h
@@ -45,17 +45,10 @@ void RequestPresent(bool secure_origin, mojom::VRSubmitFrameClientPtr submit_client, + mojom::VRPresentationProviderRequest request, RequestPresentCallback callback) override; void ExitPresent() override; - void SubmitFrame(int16_t frame_index, - const gpu::MailboxHolder& mailbox) override; - - void UpdateLayerBounds(int16_t frame_index, - mojom::VRLayerBoundsPtr left_bounds, - mojom::VRLayerBoundsPtr right_bounds, - int16_t source_width, - int16_t source_height) override; - void GetVRVSyncProvider(mojom::VRVSyncProviderRequest request) override; + void GetNextMagicWindowPose(GetNextMagicWindowPoseCallback callback) override; void RequestPresentResult(RequestPresentCallback callback, bool secure_origin,
diff --git a/device/vr/vr_display_impl_unittest.cc b/device/vr/vr_display_impl_unittest.cc index 80dc7c4..622f7e4 100644 --- a/device/vr/vr_display_impl_unittest.cc +++ b/device/vr/vr_display_impl_unittest.cc
@@ -51,8 +51,9 @@ // the FakeVRDisplay doesn't access the submit client, so a nullptr // is ok. device::mojom::VRSubmitFrameClientPtr submit_client = nullptr; + device::mojom::VRPresentationProviderRequest request = nullptr; display_impl->RequestPresent( - true, std::move(submit_client), + true, std::move(submit_client), std::move(request), base::Bind(&VRDisplayImplTest::onPresentComplete, base::Unretained(this))); }
diff --git a/device/vr/vr_service.mojom b/device/vr/vr_service.mojom index e1aceda..075bfde 100644 --- a/device/vr/vr_service.mojom +++ b/device/vr/vr_service.mojom
@@ -7,6 +7,7 @@ import "mojo/common/time.mojom"; import "gpu/ipc/common/mailbox_holder.mojom"; import "gpu/ipc/common/sync_token.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; // A field of view, given by 4 degrees describing the view from a center point. struct VRFieldOfView { @@ -56,13 +57,6 @@ VREyeParameters rightEye; }; -struct VRLayerBounds { - float left; - float top; - float width; - float height; -}; - enum VRDisplayEventReason { NONE = 0, NAVIGATION = 1, @@ -75,14 +69,14 @@ interface VRService { // TODO(shaobo.yan@intel.com, crbug/701027): Use a factory function which // takes a VRServiceClient so we will never have a half-initialized VRService. - SetClient(VRServiceClient client) => (uint32 numberOfConnectedDevices); + SetClient(VRServiceClient client) => (uint32 number_of_connected_devices); // Inform the service that the page is listening for vrdisplayactivate events. SetListeningForActivate(bool listening); }; interface VRServiceClient { OnDisplayConnected(VRDisplay display, VRDisplayClient& request, - VRDisplayInfo displayInfo); + VRDisplayInfo display_info); }; interface VRSubmitFrameClient { @@ -90,24 +84,27 @@ OnSubmitFrameRendered(); }; +// Represents a physical VR device that can be used to present WebVR content, or get orientation +// data (VRPose) when not presenting (aka magic window). interface VRDisplay { - RequestPresent(bool secureOrigin, VRSubmitFrameClient client) => (bool success); + RequestPresent(bool secure_origin, VRSubmitFrameClient client, + VRPresentationProvider& request) => (bool success); ExitPresent(); - SubmitFrame(int16 frameId, gpu.mojom.MailboxHolder mailboxHolder); - UpdateLayerBounds(int16 frameId, VRLayerBounds leftBounds, - VRLayerBounds rightBounds, int16 sourceWidth, - int16 sourceHeight); - GetVRVSyncProvider(VRVSyncProvider& request); + GetNextMagicWindowPose() => (VRPose? pose); }; -interface VRVSyncProvider { - enum Status { SUCCESS, CLOSING }; +// Provides the necessary functionality for a presenting WebVR page to draw frames for a VrDisplay. +interface VRPresentationProvider { + enum VSyncStatus { SUCCESS, CLOSING }; // The frameId maps a VSync to a frame arriving from the compositor. IDs will // be reused after the frame arrives from the compositor. Negative IDs imply // no mapping. - GetVSync() => (VRPose? pose, mojo.common.mojom.TimeDelta time, int16 frameId, - Status status); + GetVSync() => (VRPose? pose, mojo.common.mojom.TimeDelta time, int16 frame_id, + VSyncStatus status); + SubmitFrame(int16 frame_id, gpu.mojom.MailboxHolder mailbox_holder); + UpdateLayerBounds(int16 frame_id, gfx.mojom.RectF left_bounds, + gfx.mojom.RectF right_bounds, gfx.mojom.Size source_size); }; interface VRDisplayClient {
diff --git a/docs/speed/apk_size_regressions.md b/docs/speed/apk_size_regressions.md index 69dbe9d..389608d 100644 --- a/docs/speed/apk_size_regressions.md +++ b/docs/speed/apk_size_regressions.md
@@ -52,31 +52,35 @@ * Change the bug's title from `X%` to `XXkb` * Assign to commit author * Set description to (replacing **bold** parts): - > Caused by "**First line of commit message**" - > - > Commit: **abc123abc123abc123abc123abc123abc123abcd** - > - > Link to size graph: - > [https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074) - > - > Debugging size regressions is documented at: - > https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase - > - > **Optional:** - > - > It looks to me that the size increase is expected. Feel free to close as - > "Won't Fix", unless you can see some way to reduce size. - > - > **Optional:** - > - > It looks like there is something that could be done to reduce the size - > here. Adding ReleaseBlock-Stable. -Optional, but encouraged: - * In a follow-up comment, run: - ``` sh - tools/binary_size/diagnose_bloat.py GIT_REV --cloud - ``` +> Caused by "**First line of commit message**" +> +> Commit: **abc123abc123abc123abc123abc123abc123abcd** +> +> Link to size graph: +> [https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074) +> +> Debugging size regressions is documented at: +> https://chromium.googlesource.com/chromium/src/+/master/docs/speed/apk_size_regressions.md#Debugging-Apk-Size-Increase + +Optional, but encouraged: In a follow-up comment, provide some analysis: + +> Based on the graph: 20kb of native code, 8kb of pngs. +> +> **Optional:** +> +> It looks to me that the size increase is expected. Feel free to close as +> "Won't Fix", unless you can see some way to reduce size. +> +> **Optional:** +> +> It looks like there is something that could be done to reduce the size +> here. Adding ReleaseBlock-Stable. + +And if you really feel like it, run: +``` sh +tools/binary_size/diagnose_bloat.py GIT_REV --cloud +``` * Paste relevant output into the bug. # Debugging Apk Size Increase
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index 64cac120..6ca6a911 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn
@@ -109,6 +109,8 @@ if (is_chromeos) { sources += [ + "lock_screen_data/lock_screen_data_api.cc", + "lock_screen_data/lock_screen_data_api.h", "media_perception_private/conversion_utils.cc", "media_perception_private/conversion_utils.h", "media_perception_private/media_perception_api_manager.cc",
diff --git a/extensions/browser/api/lock_screen_data/OWNERS b/extensions/browser/api/lock_screen_data/OWNERS new file mode 100644 index 0000000..1b19d20 --- /dev/null +++ b/extensions/browser/api/lock_screen_data/OWNERS
@@ -0,0 +1,2 @@ +rkc@chromium.org +tbarzic@chromium.org
diff --git a/extensions/browser/api/lock_screen_data/lock_screen_data_api.cc b/extensions/browser/api/lock_screen_data/lock_screen_data_api.cc new file mode 100644 index 0000000..87943df --- /dev/null +++ b/extensions/browser/api/lock_screen_data/lock_screen_data_api.cc
@@ -0,0 +1,70 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/api/lock_screen_data/lock_screen_data_api.h" + +#include <memory> +#include <vector> + +#include "extensions/common/api/lock_screen_data.h" + +namespace extensions { + +LockScreenDataCreateFunction::LockScreenDataCreateFunction() {} + +LockScreenDataCreateFunction::~LockScreenDataCreateFunction() {} + +ExtensionFunction::ResponseAction LockScreenDataCreateFunction::Run() { + api::lock_screen_data::DataItemInfo item_info; + item_info.id = "fake"; + return RespondNow( + ArgumentList(api::lock_screen_data::Create::Results::Create(item_info))); +} + +LockScreenDataGetAllFunction::LockScreenDataGetAllFunction() {} + +LockScreenDataGetAllFunction::~LockScreenDataGetAllFunction() {} + +ExtensionFunction::ResponseAction LockScreenDataGetAllFunction::Run() { + std::vector<api::lock_screen_data::DataItemInfo> items_info; + return RespondNow( + ArgumentList(api::lock_screen_data::GetAll::Results::Create(items_info))); +} + +LockScreenDataGetContentFunction::LockScreenDataGetContentFunction() {} + +LockScreenDataGetContentFunction::~LockScreenDataGetContentFunction() {} + +ExtensionFunction::ResponseAction LockScreenDataGetContentFunction::Run() { + std::unique_ptr<api::lock_screen_data::GetContent::Params> params( + api::lock_screen_data::GetContent::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + return RespondNow(Error("Not found")); +} + +LockScreenDataSetContentFunction::LockScreenDataSetContentFunction() {} + +LockScreenDataSetContentFunction::~LockScreenDataSetContentFunction() {} + +ExtensionFunction::ResponseAction LockScreenDataSetContentFunction::Run() { + std::unique_ptr<api::lock_screen_data::SetContent::Params> params( + api::lock_screen_data::SetContent::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + return RespondNow(Error("Not found")); +} + +LockScreenDataDeleteFunction::LockScreenDataDeleteFunction() {} + +LockScreenDataDeleteFunction::~LockScreenDataDeleteFunction() {} + +ExtensionFunction::ResponseAction LockScreenDataDeleteFunction::Run() { + std::unique_ptr<api::lock_screen_data::Delete::Params> params( + api::lock_screen_data::Delete::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + return RespondNow(Error("Not found.")); +} + +} // namespace extensions
diff --git a/extensions/browser/api/lock_screen_data/lock_screen_data_api.h b/extensions/browser/api/lock_screen_data/lock_screen_data_api.h new file mode 100644 index 0000000..83c75f6 --- /dev/null +++ b/extensions/browser/api/lock_screen_data/lock_screen_data_api.h
@@ -0,0 +1,83 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_LOCK_SCREEN_DATA_API_H_ +#define EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_LOCK_SCREEN_DATA_API_H_ + +#include "base/macros.h" +#include "extensions/browser/extension_function.h" + +namespace extensions { + +class LockScreenDataCreateFunction : public UIThreadExtensionFunction { + public: + LockScreenDataCreateFunction(); + + private: + ~LockScreenDataCreateFunction() override; + + ResponseAction Run() override; + + DECLARE_EXTENSION_FUNCTION("lockScreen.data.create", LOCKSCREENDATA_CREATE); + DISALLOW_COPY_AND_ASSIGN(LockScreenDataCreateFunction); +}; + +class LockScreenDataGetAllFunction : public UIThreadExtensionFunction { + public: + LockScreenDataGetAllFunction(); + + private: + ~LockScreenDataGetAllFunction() override; + + ResponseAction Run() override; + + DECLARE_EXTENSION_FUNCTION("lockScreen.data.getAll", LOCKSCREENDATA_GETALL); + DISALLOW_COPY_AND_ASSIGN(LockScreenDataGetAllFunction); +}; + +class LockScreenDataGetContentFunction : public UIThreadExtensionFunction { + public: + LockScreenDataGetContentFunction(); + + private: + ~LockScreenDataGetContentFunction() override; + + ResponseAction Run() override; + + DECLARE_EXTENSION_FUNCTION("lockScreen.data.getContent", + LOCKSCREENDATA_GETCONTENT); + DISALLOW_COPY_AND_ASSIGN(LockScreenDataGetContentFunction); +}; + +class LockScreenDataSetContentFunction : public UIThreadExtensionFunction { + public: + LockScreenDataSetContentFunction(); + + private: + ~LockScreenDataSetContentFunction() override; + + ResponseAction Run() override; + + DECLARE_EXTENSION_FUNCTION("lockScreen.data.setContent", + LOCKSCREENDATA_SETCONTENT); + DISALLOW_COPY_AND_ASSIGN(LockScreenDataSetContentFunction); +}; + +class LockScreenDataDeleteFunction : public UIThreadExtensionFunction { + public: + LockScreenDataDeleteFunction(); + + private: + ~LockScreenDataDeleteFunction() override; + + ResponseAction Run() override; + + DECLARE_EXTENSION_FUNCTION("lockScreen.data.delete", LOCKSCREENDATA_DELETE); + + DISALLOW_COPY_AND_ASSIGN(LockScreenDataDeleteFunction); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_LOCK_SCREEN_DATA_LOCK_SCREEN_DATA_API_H_
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index 25933c0..f0c5d0fc 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h
@@ -8,7 +8,6 @@ #include <set> #include <string> #include <unordered_map> -#include <utility> #include "base/callback.h" #include "base/compiler_specific.h" @@ -242,11 +241,6 @@ kServiceWorker, }; - // An identifier for an event dispatch that is used to prevent double dispatch - // due to race conditions between the direct and lazy dispatch paths. - typedef std::tuple<const content::BrowserContext*, std::string, int> - EventDispatchIdentifier; - // TODO(gdk): Document this. static void DispatchExtensionMessage( IPC::Sender* ipc_sender, @@ -287,15 +281,6 @@ void DispatchEventImpl(const std::string& restrict_to_extension_id, const linked_ptr<Event>& event); - // Ensures that all lazy background pages that are interested in the given - // event are loaded, and queues the event if the page is not ready yet. - // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy - // event dispatch that is queued. - void DispatchLazyEvent(const std::string& extension_id, - const linked_ptr<Event>& event, - std::set<EventDispatchIdentifier>* already_dispatched, - const base::DictionaryValue* listener_filter); - // Dispatches the event to the specified extension or URL running in // |process|. void DispatchEventToProcess(const std::string& extension_id, @@ -306,15 +291,6 @@ const base::DictionaryValue* listener_filter, bool did_enqueue); - // Possibly loads given extension's background page in preparation to - // dispatch an event. Returns true if the event was queued for subsequent - // dispatch, false otherwise. - bool MaybeLoadLazyBackgroundPageToDispatchEvent( - content::BrowserContext* context, - const Extension* extension, - const linked_ptr<Event>& event, - const base::DictionaryValue* listener_filter); - // Adds a filter to an event. void AddFilterToEvent(const std::string& event_name, const std::string& extension_id,
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index 96d8733..7e4f0edd 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h
@@ -425,6 +425,7 @@ ACCESSIBILITY_PRIVATE_ON_TWO_FINGER_TOUCH_STOP, MEDIA_PERCEPTION_PRIVATE_ON_MEDIA_PERCEPTION, NETWORKING_PRIVATE_ON_CERTIFICATE_LISTS_CHANGED, + LOCK_SCREEN_DATA_ON_DATA_ITEMS_AVAILABLE, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 99526dde..2487b81 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1240,6 +1240,11 @@ NETWORKINGPRIVATE_GETCERTIFICATELISTS, ACCESSIBILITY_PRIVATE_SETSWITCHACCESSKEYS, FEEDBACKPRIVATE_READLOGSOURCE, + LOCKSCREENDATA_CREATE, + LOCKSCREENDATA_GETALL, + LOCKSCREENDATA_GETCONTENT, + LOCKSCREENDATA_SETCONTENT, + LOCKSCREENDATA_DELETE, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index 8b729a0f..21f5913 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -205,6 +205,13 @@ "dependencies": ["permission:idle"], "contexts": ["blessed_extension"] }, + "lockScreen.data": { + "dependencies": ["permission:lockScreen"], + "contexts": ["blessed_extension", "lock_screen_extension"] + }, + "lockScreen.data.create": { + "contexts": ["lock_screen_extension"] + }, "management": [{ "dependencies": ["permission:management"], "contexts": ["blessed_extension"],
diff --git a/extensions/common/api/lock_screen_data.idl b/extensions/common/api/lock_screen_data.idl new file mode 100644 index 0000000..334129b --- /dev/null +++ b/extensions/common/api/lock_screen_data.idl
@@ -0,0 +1,92 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// <p> +// The API that can be used by an app to create and manage data on the +// Chrome OS lock screen. +// </p> +// <p> +// The API usability will depend on the user session state: +// <ul> +// <li> +// When the user session is locked, the API usage will only be allowed +// from the lock screen context. +// </li> +// <li> +// When the user session is not locked, the API usage will only be +// allowed outside the lock screen context - i.e. from the regular app +// context. +// </li> +// </ul> +// </p> +// <p> +// Note that apps have reduced access to Chrome apps APIs from the lock screen +// context. +// </p> +namespace lockScreen.data { + // The basic information about available data items originating from the lock + // screen. + dictionary DataItemInfo { + // The data item ID that can later be used to retrieve and update the + // associated lock screen data. + DOMString id; + }; + + dictionary DataItemsAvailableEvent { + // <p>Whether the event was dispatched as a result of the user session + // getting unlocked. + // </p> + // <p>For example: + // <ul> + // <li>If the app creates new data items while shown on + // the lock screen, when the user unlocks the screen, + // $(ref:onDataItemsAvailable) event will be dispatched with this + // property set to <code>true</code>. + // </li> + // <li>When the user logs in, if not previously reported lock screen + // data items are found, which could happen if the user session had + // been closed while it was locked, $(ref:onDataItemsAvailable) will + // be dispatched with this property set to <code>false</code>. + // </li> + // </ul> + // </p> + boolean wasLocked; + }; + + callback DataItemCallback = void(DataItemInfo item); + callback DataItemListCallback = void(DataItemInfo[] items); + callback DataCallback = void(ArrayBuffer data); + callback VoidCallback = void(); + + interface Functions { + // Creates a new data item reference - available only in lock screen + // contexts. + static void create(DataItemCallback callback); + + // Gets references to all data items available to the app. + static void getAll(DataItemListCallback callback); + + // Retrieves content of the data item identified by |id|. + static void getContent(DOMString id, DataCallback callback); + + // Sets contents of a data item. + // |id| - Identifies the target data item. + // |data| - The data item contents to set. + static void setContent(DOMString id, + ArrayBuffer data, + optional VoidCallback callback); + + // Deletes a data item. The data item will not be available through this + // API anymore. + // |id| - Identifies the data item to delete. + static void delete(DOMString id, optional VoidCallback callback); + }; + + interface Events { + // Dispatched when new data items become available to main, non-lock screen + // app context - this event is not expected to be dispatched to the app in + // the lock screen context. + static void onDataItemsAvailable(DataItemsAvailableEvent event); + }; +};
diff --git a/extensions/common/api/schema.gni b/extensions/common/api/schema.gni index 908ae44..d3415c8 100644 --- a/extensions/common/api/schema.gni +++ b/extensions/common/api/schema.gni
@@ -58,6 +58,7 @@ if (is_chromeos) { extensions_api_schema_files_ += [ "diagnostics.idl", + "lock_screen_data.idl", "media_perception_private.idl", "networking_config.idl", "vpn_provider.idl",
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index 0d60002..5fdf8fc 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -350,6 +350,10 @@ hr = video_device_->CreateVideoProcessor(video_processor_enumerator_.Get(), 0, video_processor_.GetAddressOf()); CHECK(SUCCEEDED(hr)); + + // Auto stream processing (the default) can hurt power consumption. + video_context_->VideoProcessorSetStreamAutoProcessingMode( + video_processor_.Get(), 0, FALSE); } base::win::ScopedComPtr<IDXGISwapChain1> @@ -640,9 +644,6 @@ video_context_->VideoProcessorSetStreamSourceRect(video_processor_.Get(), 0, TRUE, &source_rect); - video_context_->VideoProcessorSetStreamAutoProcessingMode( - video_processor_.Get(), 0, FALSE); - hr = video_context_->VideoProcessorBlt(video_processor_.Get(), out_view_.Get(), 0, 1, &stream); CHECK(SUCCEEDED(hr));
diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index 7301f6f..786b64c 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc
@@ -68,7 +68,8 @@ std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, - mojom::CommandBufferIdPtr command_buffer_id) { + mojom::CommandBufferIdPtr command_buffer_id, + OutputWithReleaseMailboxCB output_cb) { static_cast<void>(media_gpu_channel_manager_); // TODO(sandersd): Factory for VideoDecoders.
diff --git a/media/mojo/services/gpu_mojo_media_client.h b/media/mojo/services/gpu_mojo_media_client.h index 3ed67ae..9be197bc 100644 --- a/media/mojo/services/gpu_mojo_media_client.h +++ b/media/mojo/services/gpu_mojo_media_client.h
@@ -31,7 +31,8 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) final; std::unique_ptr<VideoDecoder> CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, - mojom::CommandBufferIdPtr command_buffer_id) final; + mojom::CommandBufferIdPtr command_buffer_id, + OutputWithReleaseMailboxCB output_cb) final; std::unique_ptr<CdmFactory> CreateCdmFactory( service_manager::mojom::InterfaceProvider* interface_provider) final;
diff --git a/media/mojo/services/mojo_media_client.cc b/media/mojo/services/mojo_media_client.cc index 59e657e2..6c9207a 100644 --- a/media/mojo/services/mojo_media_client.cc +++ b/media/mojo/services/mojo_media_client.cc
@@ -28,7 +28,8 @@ std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, - mojom::CommandBufferIdPtr command_buffer_id) { + mojom::CommandBufferIdPtr command_buffer_id, + OutputWithReleaseMailboxCB output_cb) { return nullptr; }
diff --git a/media/mojo/services/mojo_media_client.h b/media/mojo/services/mojo_media_client.h index 442481cf4..a3e64921 100644 --- a/media/mojo/services/mojo_media_client.h +++ b/media/mojo/services/mojo_media_client.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "media/mojo/interfaces/video_decoder.mojom.h" #include "media/mojo/services/media_mojo_export.h" @@ -16,6 +17,10 @@ class SingleThreadTaskRunner; } +namespace gpu { +struct SyncToken; +} + namespace service_manager { class Connector; namespace mojom { @@ -31,10 +36,17 @@ class MediaLog; class RendererFactory; class VideoDecoder; +class VideoFrame; class VideoRendererSink; class MEDIA_MOJO_EXPORT MojoMediaClient { public: + // Currently using the same signature as VideoFrame::ReleaseMailboxCB. + using ReleaseMailboxCB = base::Callback<void(const gpu::SyncToken&)>; + + using OutputWithReleaseMailboxCB = + base::Callback<void(ReleaseMailboxCB, const scoped_refptr<VideoFrame>&)>; + // Called before the host application is scheduled to quit. // The application message loop is still valid at this point, so all clean // up tasks requiring the message loop must be completed before returning. @@ -47,9 +59,12 @@ virtual std::unique_ptr<AudioDecoder> CreateAudioDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner); + // TODO(sandersd): |output_cb| should not be required. + // See https://crbug.com/733828. virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder( scoped_refptr<base::SingleThreadTaskRunner> task_runner, - mojom::CommandBufferIdPtr command_buffer_id); + mojom::CommandBufferIdPtr command_buffer_id, + OutputWithReleaseMailboxCB output_cb); // Returns the output sink used for rendering audio on |audio_device_id|. // May be null if the RendererFactory doesn't need an audio sink.
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc index d591cab..a6154ec 100644 --- a/media/mojo/services/mojo_video_decoder_service.cc +++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -36,13 +36,13 @@ mojom::CommandBufferIdPtr command_buffer_id) { DVLOG(1) << __func__; - // TODO(sandersd): Enter an error state. + // TODO(sandersd): Close the channel. if (decoder_) return; - // TODO(sandersd): Provide callback for requesting a GpuCommandBufferStub. decoder_ = mojo_media_client_->CreateVideoDecoder( - base::ThreadTaskRunnerHandle::Get(), std::move(command_buffer_id)); + base::ThreadTaskRunnerHandle::Get(), std::move(command_buffer_id), + base::Bind(&MojoVideoDecoderService::OnDecoderOutput, weak_this_)); client_.Bind(std::move(client)); @@ -64,7 +64,8 @@ config.To<VideoDecoderConfig>(), low_delay, nullptr, base::Bind(&MojoVideoDecoderService::OnDecoderInitialized, weak_this_, callback), - base::Bind(&MojoVideoDecoderService::OnDecoderOutput, weak_this_)); + base::Bind(&MojoVideoDecoderService::OnDecoderOutput, weak_this_, + MojoMediaClient::ReleaseMailboxCB())); } void MojoVideoDecoderService::Decode(mojom::DecoderBufferPtr buffer, @@ -105,8 +106,7 @@ void MojoVideoDecoderService::OnDecoderRead( const DecodeCallback& callback, scoped_refptr<DecoderBuffer> buffer) { - // TODO(sandersd): After a decode error, we should enter an error state and - // reject all future method calls. + // TODO(sandersd): Close the channel. if (!buffer) { callback.Run(DecodeStatus::DECODE_ERROR); return; @@ -131,16 +131,34 @@ } void MojoVideoDecoderService::OnDecoderOutput( + MojoMediaClient::ReleaseMailboxCB release_cb, const scoped_refptr<VideoFrame>& frame) { DVLOG(2) << __func__; DCHECK(client_); - client_->OnVideoFrameDecoded(frame, base::nullopt); + + base::Optional<base::UnguessableToken> release_token; + if (release_cb) { + release_token = base::UnguessableToken::Create(); + release_mailbox_cbs_[*release_token] = std::move(release_cb); + } + + client_->OnVideoFrameDecoded(frame, std::move(release_token)); } void MojoVideoDecoderService::OnReleaseMailbox( const base::UnguessableToken& release_token, const gpu::SyncToken& release_sync_token) { DVLOG(2) << __func__; + + // TODO(sandersd): Is it a serious error for the client to call + // OnReleaseMailbox() with an invalid |release_token|? + auto it = release_mailbox_cbs_.find(release_token); + if (it == release_mailbox_cbs_.end()) + return; + + MojoMediaClient::ReleaseMailboxCB cb = std::move(it->second); + release_mailbox_cbs_.erase(it); + std::move(cb).Run(release_sync_token); } } // namespace media
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index c03e1f0..54e91a2c 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -5,12 +5,15 @@ #ifndef MEDIA_MOJO_SERVICES_MOJO_VIDEO_DECODER_SERVICE_H_ #define MEDIA_MOJO_SERVICES_MOJO_VIDEO_DECODER_SERVICE_H_ +#include <map> #include <memory> #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/unguessable_token.h" #include "media/base/decode_status.h" #include "media/mojo/interfaces/video_decoder.mojom.h" +#include "media/mojo/services/mojo_media_client.h" namespace gpu { struct SyncToken; @@ -55,13 +58,16 @@ void OnDecoderDecoded(const DecodeCallback& callback, DecodeStatus status); void OnDecoderReset(const ResetCallback& callback); - void OnDecoderOutput(const scoped_refptr<VideoFrame>& frame); + void OnDecoderOutput(MojoMediaClient::ReleaseMailboxCB, + const scoped_refptr<VideoFrame>& frame); mojom::VideoDecoderClientAssociatedPtr client_; std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_; MojoMediaClient* mojo_media_client_; std::unique_ptr<media::VideoDecoder> decoder_; + std::map<base::UnguessableToken, MojoMediaClient::ReleaseMailboxCB> + release_mailbox_cbs_; base::WeakPtr<MojoVideoDecoderService> weak_this_; base::WeakPtrFactory<MojoVideoDecoderService> weak_factory_;
diff --git a/mojo/edk/js/tests/BUILD.gn b/mojo/edk/js/tests/BUILD.gn index 21c9bfc4..b3b87392 100644 --- a/mojo/edk/js/tests/BUILD.gn +++ b/mojo/edk/js/tests/BUILD.gn
@@ -15,44 +15,10 @@ group("tests") { testonly = true deps = [ - ":mojo_js_integration_tests", ":mojo_js_unittests", ] } -test("mojo_js_integration_tests") { - deps = [ - ":js_to_cpp_bindings", - "//base/test:test_support", - "//gin:gin_test", - "//mojo/common", - "//mojo/edk/js", - "//mojo/edk/test:run_all_unittests", - "//mojo/public/cpp/bindings", - "//mojo/public/cpp/system", - "//mojo/public/js:bindings", - ] - - sources = [ - "js_to_cpp_tests.cc", - ] - - data = [ - "js_to_cpp_tests.js", - ] - - configs += [ "//v8:external_startup_data" ] -} - -mojom("js_to_cpp_bindings") { - sources = [ - "js_to_cpp.mojom", - ] - - # TODO(crbug.com/699569): Convert to use the new JS bindings. - use_new_js_bindings = false -} - test("mojo_js_unittests") { deps = [ "//base",
diff --git a/mojo/edk/js/tests/js_to_cpp_tests.cc b/mojo/edk/js/tests/js_to_cpp_tests.cc deleted file mode 100644 index 0ce95e8..0000000 --- a/mojo/edk/js/tests/js_to_cpp_tests.cc +++ /dev/null
@@ -1,459 +0,0 @@ -// 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. - -#include <stddef.h> -#include <stdint.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/at_exit.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_task_environment.h" -#include "base/threading/thread_task_runner_handle.h" -#include "gin/array_buffer.h" -#include "gin/public/isolate_holder.h" -#include "gin/v8_initializer.h" -#include "mojo/common/data_pipe_utils.h" -#include "mojo/edk/js/mojo_runner_delegate.h" -#include "mojo/edk/js/tests/js_to_cpp.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "mojo/public/cpp/bindings/lib/validation_errors.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/cpp/system/wait.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace edk { -namespace js { - -// Global value updated by some checks to prevent compilers from optimizing -// reads out of existence. -uint32_t g_waste_accumulator = 0; - -namespace { - -// Negative numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const int8_t kExpectedInt8Value = -65; -const int16_t kExpectedInt16Value = -16961; -const int32_t kExpectedInt32Value = -1145258561; -const int64_t kExpectedInt64Value = -77263311946305LL; - -// Positive numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const uint8_t kExpectedUInt8Value = 65; -const uint16_t kExpectedUInt16Value = 16961; -const uint32_t kExpectedUInt32Value = 1145258561; -const uint64_t kExpectedUInt64Value = 77263311946305LL; - -// Double/float values, including special case constants. -const double kExpectedDoubleVal = 3.14159265358979323846; -const double kExpectedDoubleInf = std::numeric_limits<double>::infinity(); -const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN(); -const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal); -const float kExpectedFloatInf = std::numeric_limits<float>::infinity(); -const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN(); - -// NaN has the property that it is not equal to itself. -#define EXPECT_NAN(x) EXPECT_NE(x, x) - -void CheckDataPipe(ScopedDataPipeConsumerHandle data_pipe_handle) { - std::string buffer; - bool result = common::BlockingCopyToString(std::move(data_pipe_handle), - &buffer); - EXPECT_TRUE(result); - EXPECT_EQ(64u, buffer.size()); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(i, buffer[i]); - } -} - -void CheckMessagePipe(MessagePipeHandle message_pipe_handle) { - MojoResult result = Wait(message_pipe_handle, MOJO_HANDLE_SIGNAL_READABLE); - EXPECT_EQ(MOJO_RESULT_OK, result); - std::vector<uint8_t> bytes; - std::vector<ScopedHandle> handles; - result = ReadMessageRaw(message_pipe_handle, &bytes, &handles, 0); - EXPECT_EQ(MOJO_RESULT_OK, result); - EXPECT_EQ(64u, bytes.size()); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(255 - i, bytes[i]); - } -} - -js_to_cpp::EchoArgsPtr BuildSampleEchoArgs() { - js_to_cpp::EchoArgsPtr args(js_to_cpp::EchoArgs::New()); - args->si64 = kExpectedInt64Value; - args->si32 = kExpectedInt32Value; - args->si16 = kExpectedInt16Value; - args->si8 = kExpectedInt8Value; - args->ui64 = kExpectedUInt64Value; - args->ui32 = kExpectedUInt32Value; - args->ui16 = kExpectedUInt16Value; - args->ui8 = kExpectedUInt8Value; - args->float_val = kExpectedFloatVal; - args->float_inf = kExpectedFloatInf; - args->float_nan = kExpectedFloatNan; - args->double_val = kExpectedDoubleVal; - args->double_inf = kExpectedDoubleInf; - args->double_nan = kExpectedDoubleNan; - args->name.emplace("coming"); - args->string_array.emplace(3); - (*args->string_array)[0] = "one"; - (*args->string_array)[1] = "two"; - (*args->string_array)[2] = "three"; - return args; -} - -void CheckSampleEchoArgs(js_to_cpp::EchoArgsPtr arg) { - EXPECT_EQ(kExpectedInt64Value, arg->si64); - EXPECT_EQ(kExpectedInt32Value, arg->si32); - EXPECT_EQ(kExpectedInt16Value, arg->si16); - EXPECT_EQ(kExpectedInt8Value, arg->si8); - EXPECT_EQ(kExpectedUInt64Value, arg->ui64); - EXPECT_EQ(kExpectedUInt32Value, arg->ui32); - EXPECT_EQ(kExpectedUInt16Value, arg->ui16); - EXPECT_EQ(kExpectedUInt8Value, arg->ui8); - EXPECT_EQ(kExpectedFloatVal, arg->float_val); - EXPECT_EQ(kExpectedFloatInf, arg->float_inf); - EXPECT_NAN(arg->float_nan); - EXPECT_EQ(kExpectedDoubleVal, arg->double_val); - EXPECT_EQ(kExpectedDoubleInf, arg->double_inf); - EXPECT_NAN(arg->double_nan); - EXPECT_EQ(std::string("coming"), *arg->name); - EXPECT_EQ(std::string("one"), (*arg->string_array)[0]); - EXPECT_EQ(std::string("two"), (*arg->string_array)[1]); - EXPECT_EQ(std::string("three"), (*arg->string_array)[2]); - CheckDataPipe(std::move(arg->data_handle)); - CheckMessagePipe(arg->message_handle.get()); -} - -void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckSampleEchoArgs(std::move(list->item)); - CheckSampleEchoArgsList(list->next); -} - -// More forgiving checks are needed in the face of potentially corrupt -// messages. The values don't matter so long as all accesses are within -// bounds. -void CheckCorruptedString(const std::string& arg) { - for (size_t i = 0; i < arg.size(); ++i) - g_waste_accumulator += arg[i]; -} - -void CheckCorruptedString(const base::Optional<std::string>& arg) { - if (!arg) - return; - CheckCorruptedString(*arg); -} - -void CheckCorruptedStringArray( - const base::Optional<std::vector<std::string>>& string_array) { - if (!string_array) - return; - for (size_t i = 0; i < string_array->size(); ++i) - CheckCorruptedString((*string_array)[i]); -} - -void CheckCorruptedDataPipe(MojoHandle data_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = MojoReadData( - data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < buffer_size; ++i) - g_waste_accumulator += buffer[i]; -} - -void CheckCorruptedMessagePipe(MojoHandle message_pipe_handle) { - std::vector<uint8_t> bytes; - std::vector<ScopedHandle> handles; - MojoResult result = ReadMessageRaw(MessagePipeHandle(message_pipe_handle), - &bytes, &handles, 0); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < bytes.size(); ++i) - g_waste_accumulator += bytes[i]; -} - -void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgsPtr& arg) { - if (arg.is_null()) - return; - CheckCorruptedString(arg->name); - CheckCorruptedStringArray(arg->string_array); - if (arg->data_handle.is_valid()) - CheckCorruptedDataPipe(arg->data_handle.get().value()); - if (arg->message_handle.is_valid()) - CheckCorruptedMessagePipe(arg->message_handle.get().value()); -} - -void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckCorruptedEchoArgs(list->item); - CheckCorruptedEchoArgsList(list->next); -} - -// Base Provider implementation class. It's expected that tests subclass and -// override the appropriate Provider functions. When test is done quit the -// run_loop(). -class CppSideConnection : public js_to_cpp::CppSide { - public: - CppSideConnection() - : run_loop_(nullptr), - js_side_(nullptr), - mishandled_messages_(0), - binding_(this) {} - ~CppSideConnection() override {} - - void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; } - base::RunLoop* run_loop() { return run_loop_; } - - void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; } - js_to_cpp::JsSide* js_side() { return js_side_; } - - void Bind(InterfaceRequest<js_to_cpp::CppSide> request) { - binding_.Bind(std::move(request)); - // Keep the pipe open even after validation errors. - binding_.EnableTestingMode(); - } - - // js_to_cpp::CppSide: - void StartTest() override { NOTREACHED(); } - - void TestFinished() override { NOTREACHED(); } - - void PingResponse() override { mishandled_messages_ += 1; } - - void EchoResponse(js_to_cpp::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - void BitFlipResponse( - js_to_cpp::EchoArgsListPtr list, - js_to_cpp::ForTestingAssociatedPtrInfo not_used) override { - mishandled_messages_ += 1; - } - - void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - protected: - base::RunLoop* run_loop_; - js_to_cpp::JsSide* js_side_; - int mishandled_messages_; - mojo::Binding<js_to_cpp::CppSide> binding_; - - private: - DISALLOW_COPY_AND_ASSIGN(CppSideConnection); -}; - -// Trivial test to verify a message sent from JS is received. -class PingCppSideConnection : public CppSideConnection { - public: - PingCppSideConnection() : got_message_(false) {} - ~PingCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->Ping(); } - - void PingResponse() override { - got_message_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return got_message_ && !mishandled_messages_; - } - - private: - bool got_message_; - DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection); -}; - -// Test that parameters are passed with correct values. -class EchoCppSideConnection : public CppSideConnection { - public: - EchoCppSideConnection() : - message_count_(0), - termination_seen_(false) { - } - ~EchoCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { - js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs()); - } - - void EchoResponse(js_to_cpp::EchoArgsListPtr list) override { - const js_to_cpp::EchoArgsPtr& special_arg = list->item; - message_count_ += 1; - EXPECT_EQ(-1, special_arg->si64); - EXPECT_EQ(-1, special_arg->si32); - EXPECT_EQ(-1, special_arg->si16); - EXPECT_EQ(-1, special_arg->si8); - EXPECT_EQ(std::string("going"), *special_arg->name); - CheckSampleEchoArgsList(list->next); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_ && - !mishandled_messages_ && - message_count_ == kExpectedMessageCount; - } - - private: - static const int kExpectedMessageCount = 10; - int message_count_; - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection); -}; - -// Test that corrupted messages don't wreak havoc. -class BitFlipCppSideConnection : public CppSideConnection { - public: - BitFlipCppSideConnection() : termination_seen_(false) {} - ~BitFlipCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); } - - void BitFlipResponse( - js_to_cpp::EchoArgsListPtr list, - js_to_cpp::ForTestingAssociatedPtrInfo not_used) override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_; - } - - private: - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection); -}; - -// Test that severely random messages don't wreak havoc. -class BackPointerCppSideConnection : public CppSideConnection { - public: - BackPointerCppSideConnection() : termination_seen_(false) {} - ~BackPointerCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); } - - void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_; - } - - private: - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection); -}; - -} // namespace - -class JsToCppTest : public testing::Test { - public: - JsToCppTest() {} - - void RunTest(const std::string& test, CppSideConnection* cpp_side) { - cpp_side->set_run_loop(&run_loop_); - - js_to_cpp::JsSidePtr js_side; - auto js_side_proxy = MakeRequest(&js_side); - - cpp_side->set_js_side(js_side.get()); - js_to_cpp::CppSidePtr cpp_side_ptr; - cpp_side->Bind(MakeRequest(&cpp_side_ptr)); - - js_side->SetCppSide(std::move(cpp_side_ptr)); - -#ifdef V8_USE_EXTERNAL_STARTUP_DATA - gin::V8Initializer::LoadV8Snapshot(); - gin::V8Initializer::LoadV8Natives(); -#endif - - gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode, - gin::IsolateHolder::kStableV8Extras, - gin::ArrayBufferAllocator::SharedInstance()); - gin::IsolateHolder instance(base::ThreadTaskRunnerHandle::Get()); - MojoRunnerDelegate delegate; - gin::ShellRunner runner(&delegate, instance.isolate()); - delegate.Start(&runner, js_side_proxy.PassMessagePipe().release().value(), - test); - - run_loop_.Run(); - } - - private: - base::ShadowingAtExitManager at_exit_; - base::test::ScopedTaskEnvironment scoped_task_environment_; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(JsToCppTest); -}; - -TEST_F(JsToCppTest, Ping) { - PingCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, Echo) { - EchoCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, BitFlip) { - // These tests generate a lot of expected validation errors. Suppress logging. - mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; - - BitFlipCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, BackPointer) { - // These tests generate a lot of expected validation errors. Suppress logging. - mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; - - BackPointerCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -} // namespace js -} // namespace edk -} // namespace mojo
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index f855f47..6dac9881 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -41,47 +41,28 @@ ] } -android_library("embedded_test_server_aidl_java") { - testonly = true - deps = [ - "//third_party/android_tools:android_support_annotations_java", - ] - srcjar_deps = [ ":embedded_test_server_aidl" ] -} - android_library("net_java_test_support") { testonly = true java_files = [ + "../test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticator.java", + "../test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticatorService.java", "../test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java", + "../test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java", + "../test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerService.java", "../test/android/javatests/src/org/chromium/net/test/util/CertTestUtil.java", "../test/android/javatests/src/org/chromium/net/test/util/NetworkChangeNotifierTestUtil.java", "../test/android/javatests/src/org/chromium/net/test/util/TestWebServer.java", ] deps = [ - ":embedded_test_server_aidl_java", ":net_java", "//base:base_java", "//base:base_java_test_support", "//third_party/android_tools:android_support_annotations_java", "//third_party/junit", ] - srcjar_deps = [ ":net_java_test_support_enums_srcjar" ] -} - -android_library("net_java_test_support_provider") { - testonly = true - java_files = [ - "../test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticator.java", - "../test/android/javatests/src/org/chromium/net/test/DummySpnegoAuthenticatorService.java", - "../test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerImpl.java", - "../test/android/javatests/src/org/chromium/net/test/EmbeddedTestServerService.java", - ] - - deps = [ - ":embedded_test_server_aidl_java", - ":net_java", - "//base:base_java", - "//base:base_java_test_support", + srcjar_deps = [ + ":embedded_test_server_aidl", + ":net_java_test_support_enums_srcjar", ] } @@ -118,7 +99,6 @@ never_incremental = true deps = [ ":net_java_test_support", - ":net_java_test_support_provider", "//base:base_java", ] android_manifest = "../test/android/javatests/AndroidManifest.xml"
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc index 84cdfc43..bd6d819e 100644 --- a/net/cert/cert_verify_proc_mac.cc +++ b/net/cert/cert_verify_proc_mac.cc
@@ -337,8 +337,10 @@ // Root should have matching policy in EVRootCAMetadata. std::string der_cert; - if (!X509Certificate::GetDEREncoded(os_cert_chain.back(), &der_cert)) + if (os_cert_chain.empty() || + !X509Certificate::GetDEREncoded(os_cert_chain.back(), &der_cert)) { return false; + } SHA1HashValue weak_fingerprint; base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(der_cert.data()), der_cert.size(), weak_fingerprint.data);
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index beae1af..fec9c33c 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -25,6 +25,7 @@ #include "net/cert/cert_verify_result.h" #include "net/cert/crl_set.h" #include "net/cert/crl_set_storage.h" +#include "net/cert/ev_root_ca_metadata.h" #include "net/cert/internal/signature_algorithm.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" @@ -183,6 +184,16 @@ #endif }; +// Returns true if a test root added through ScopedTestRoot can verify +// successfully as a target certificate with chain of length 1 on the given +// CertVerifyProcType. +bool ScopedTestRootCanTrustTargetCert(CertVerifyProcType verify_proc_type) { + return verify_proc_type == CERT_VERIFY_PROC_MAC || + verify_proc_type == CERT_VERIFY_PROC_IOS || + verify_proc_type == CERT_VERIFY_PROC_NSS || + verify_proc_type == CERT_VERIFY_PROC_ANDROID; +} + } // namespace // This fixture is for tests that apply to concrete implementations of @@ -346,6 +357,79 @@ EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); } +// Target cert has an EV policy, and verifies successfully, but has a chain of +// length 1 because the target cert was directly trusted in the trust store. +// Should verify OK but not with STATUS_IS_EV. +TEST_P(CertVerifyProcInternalTest, TrustedTargetCertWithEVPolicy) { + // The policy that "explicit-policy-chain.pem" target certificate asserts. + static const char kEVTestCertPolicy[] = "1.2.3.4"; + ScopedTestEVPolicy scoped_test_ev_policy(EVRootCAMetadata::GetInstance(), + SHA1HashValue(), kEVTestCertPolicy); + + scoped_refptr<X509Certificate> cert = + ImportCertFromFile(GetTestCertsDirectory(), "explicit-policy-chain.pem"); + ASSERT_TRUE(cert); + ScopedTestRoot scoped_test_root(cert.get()); + + CertVerifyResult verify_result; + int flags = CertVerifier::VERIFY_EV_CERT; + int error = Verify(cert.get(), "policy_test.example", flags, + nullptr /*crl_set*/, CertificateList(), &verify_result); + // TODO(eroman): builtin verifier cannot verify a chain of length 1. + if (verify_proc_type() == CERT_VERIFY_PROC_BUILTIN) { + EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); + } else if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) { + EXPECT_THAT(error, IsOk()); + ASSERT_TRUE(verify_result.verified_cert); + EXPECT_TRUE( + verify_result.verified_cert->GetIntermediateCertificates().empty()); + } else { + EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); + } + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); +} + +// Target cert has an EV policy, and verifies successfully with a chain of +// length 1, and its fingerprint matches the cert fingerprint for that ev +// policy. This should never happen in reality, but just test that things don't +// explode if it does. +TEST_P(CertVerifyProcInternalTest, + TrustedTargetCertWithEVPolicyAndEVFingerprint) { + // The policy that "explicit-policy-chain.pem" target certificate asserts. + static const char kEVTestCertPolicy[] = "1.2.3.4"; + // This the fingerprint of the "explicit-policy-chain.pem" target certificate. + // See net/data/ssl/certificates/explicit-policy-chain.pem + static const SHA1HashValue kEVTestCertFingerprint = { + {0x45, 0x1f, 0x20, 0x51, 0x97, 0xe9, 0x41, 0x96, 0xc4, 0xd8, + 0x5f, 0x83, 0xc7, 0x52, 0x6e, 0x90, 0x1f, 0x87, 0x5b, 0xd4}}; + ScopedTestEVPolicy scoped_test_ev_policy(EVRootCAMetadata::GetInstance(), + kEVTestCertFingerprint, + kEVTestCertPolicy); + + scoped_refptr<X509Certificate> cert = + ImportCertFromFile(GetTestCertsDirectory(), "explicit-policy-chain.pem"); + ASSERT_TRUE(cert); + ScopedTestRoot scoped_test_root(cert.get()); + + CertVerifyResult verify_result; + int flags = CertVerifier::VERIFY_EV_CERT; + int error = Verify(cert.get(), "policy_test.example", flags, + nullptr /*crl_set*/, CertificateList(), &verify_result); + // TODO(eroman): builtin verifier cannot verify a chain of length 1. + if (verify_proc_type() == CERT_VERIFY_PROC_BUILTIN) { + EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); + } else if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) { + EXPECT_THAT(error, IsOk()); + ASSERT_TRUE(verify_result.verified_cert); + EXPECT_TRUE( + verify_result.verified_cert->GetIntermediateCertificates().empty()); + } else { + EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); + } + // An EV Root certificate should never be used as an end-entity certificate. + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); +} + // TODO(crbug.com/605457): the test expectation was incorrect on some // configurations, so disable the test until it is fixed (better to have // a bug to track a failing test than a false sense of security due to
diff --git a/net/cert/test_root_certs_nss.cc b/net/cert/test_root_certs_nss.cc index 6f9cc8ad..f6c489b 100644 --- a/net/cert/test_root_certs_nss.cc +++ b/net/cert/test_root_certs_nss.cc
@@ -43,7 +43,7 @@ // Change the trust bits to unconditionally trust this certificate. CERTCertTrust new_trust; - rv = CERT_DecodeTrustString(&new_trust, "TCu,Cu,Tu"); + rv = CERT_DecodeTrustString(&new_trust, "TCPu,Cu,Tu"); if (rv != SECSuccess) { LOG(ERROR) << "Cannot decode certificate trust string."; return false;
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index efd985b..2d4fb59 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -10136,6 +10136,9 @@ ], "gtest_tests": [ { + "args": [ + "--test-launcher-filter-file=testing/buildbot/filters/fuchsia.base_unittests.filter" + ], "swarming": { "can_use_on_swarming_builders": false }, @@ -10150,6 +10153,9 @@ ], "gtest_tests": [ { + "args": [ + "--test-launcher-filter-file=testing/buildbot/filters/fuchsia.base_unittests.filter" + ], "swarming": { "can_use_on_swarming_builders": false },
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index e86d814..6f3f0b43 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -3967,12 +3967,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "mojo_js_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "mojo_js_unittests" }, { @@ -4648,12 +4642,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "mojo_js_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "mojo_js_unittests" }, {
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index a6dc3e2..96c882a 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -24,7 +24,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -54,7 +54,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -84,7 +84,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -114,7 +114,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -144,7 +144,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -174,7 +174,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -204,7 +204,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -234,7 +234,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -264,7 +264,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -294,7 +294,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -324,7 +324,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -354,7 +354,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -384,7 +384,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -414,7 +414,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -444,7 +444,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -474,7 +474,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -504,7 +504,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -534,7 +534,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -564,7 +564,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -594,7 +594,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -624,7 +624,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -654,7 +654,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -684,7 +684,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -714,7 +714,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -744,7 +744,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -774,7 +774,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -804,7 +804,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -834,7 +834,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -864,7 +864,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -894,7 +894,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -924,7 +924,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -954,7 +954,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -984,7 +984,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1014,7 +1014,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1044,7 +1044,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1074,7 +1074,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1104,7 +1104,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1134,7 +1134,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1164,7 +1164,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1194,7 +1194,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1224,7 +1224,7 @@ "android_devices": "1", "id": "build243-m4--device2", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1254,7 +1254,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1284,7 +1284,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1314,7 +1314,7 @@ "android_devices": "1", "id": "build243-m4--device2", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1344,7 +1344,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1374,7 +1374,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1404,7 +1404,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1434,7 +1434,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1464,7 +1464,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1494,7 +1494,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1524,7 +1524,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1554,7 +1554,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1584,7 +1584,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1614,7 +1614,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1644,7 +1644,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1674,7 +1674,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1704,7 +1704,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1734,7 +1734,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1764,7 +1764,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1794,7 +1794,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1824,7 +1824,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1854,7 +1854,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1884,7 +1884,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1914,7 +1914,7 @@ "android_devices": "1", "id": "build243-m4--device1", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1944,7 +1944,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -1974,7 +1974,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2004,7 +2004,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2034,7 +2034,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2064,7 +2064,7 @@ "android_devices": "1", "id": "build243-m4--device2", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2094,7 +2094,7 @@ "android_devices": "1", "id": "build243-m4--device3", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2124,7 +2124,7 @@ "android_devices": "1", "id": "build243-m4--device2", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2154,7 +2154,7 @@ "android_devices": "1", "id": "build243-m4--device1", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2184,7 +2184,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2214,7 +2214,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2244,7 +2244,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2274,7 +2274,7 @@ "android_devices": "1", "id": "build243-m4--device4", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2304,7 +2304,7 @@ "android_devices": "1", "id": "build243-m4--device5", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2334,7 +2334,7 @@ "android_devices": "1", "id": "build243-m4--device2", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2364,7 +2364,7 @@ "android_devices": "1", "id": "build243-m4--device6", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2394,7 +2394,7 @@ "android_devices": "1", "id": "build243-m4--device1", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2424,7 +2424,7 @@ "android_devices": "1", "id": "build243-m4--device1", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000, @@ -2454,7 +2454,7 @@ "android_devices": "1", "id": "build243-m4--device7", "os": "Android", - "pool": "Chrome-perf" + "pool": "Chrome-perf-fyi" } ], "expiration": 36000,
diff --git a/testing/buildbot/client.v8.chromium.json b/testing/buildbot/client.v8.chromium.json index bb493a0..09e30211 100644 --- a/testing/buildbot/client.v8.chromium.json +++ b/testing/buildbot/client.v8.chromium.json
@@ -236,12 +236,6 @@ "swarming": { "can_use_on_swarming_builders": true }, - "test": "mojo_js_integration_tests" - }, - { - "swarming": { - "can_use_on_swarming_builders": true - }, "test": "mojo_js_unittests" }, {
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter new file mode 100644 index 0000000..8bc6fd19 --- /dev/null +++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -0,0 +1,207 @@ +# TODO(fuchsia): Being ported, see https://crbug.com/706592. + +-ActivityTrackerTest.BasicTest +-ActivityTrackerTest.CreateWithFileTest +-ActivityTrackerTest.ProcessDeathTest +-ActivityTrackerTest.ThreadDeathTest +-AllocationRegisterTest.ChangeContextAfterInsertion +-AllocationRegisterTest.DoubleFreeIsAllowed +-AllocationRegisterTest.DoubleInsertOverwrites +-AllocationRegisterTest.InsertRemove +-AllocationRegisterTest.InsertRemoveCollisions +-AllocationRegisterTest.InsertRemoveRandomOrder +-AllocationRegisterTest.OverflowAllocationTest +-AllocationRegisterTest.OverflowBacktraceTest +-CrashLoggingTest.ChunkValue +-CrashLoggingTest.InitSize +-CrashLoggingTest.ScopedCrashKey +-CrashLoggingTest.SetChunked +-CrashLoggingTest.SetClearSingle +-DirReaderPosixUnittest.Read +-DiscardableSharedMemoryTest.Close +-DiscardableSharedMemoryTest.CreateAndMap +-DiscardableSharedMemoryTest.CreateFromHandle +-DiscardableSharedMemoryTest.LastUsed +-DiscardableSharedMemoryTest.LockAndUnlock +-DiscardableSharedMemoryTest.LockAndUnlockRange +-DiscardableSharedMemoryTest.LockShouldAlwaysFailAfterSuccessfulPurge +-DiscardableSharedMemoryTest.MappedSize +-DiscardableSharedMemoryTest.Purge +-DiscardableSharedMemoryTest.ZeroSize +-FeatureListTest.StoreAndRetrieveAssociatedFeaturesFromSharedMemory +-FeatureListTest.StoreAndRetrieveFeaturesFromSharedMemory +-FieldTrialListTest.AddTrialsToAllocator +-FieldTrialListTest.AssociateFieldTrialParams +-FieldTrialListTest.ClearParamsFromSharedMemory +-FieldTrialListTest.DoNotAddSimulatedFieldTrialsToAllocator +-FieldTrialListTest.DumpAndFetchFromSharedMemory +-FieldTrialListTest.InstantiateAllocator +-FieldTrialListTest.SerializeSharedMemoryHandleMetadata +-FileLockingTest.LockAndUnlock +-FileLockingTest.UnlockOnClose +-FileLockingTest.UnlockOnExit +-FileLockingTest.UnlockOnTerminate +-FilePathTest.FromUTF8Unsafe_And_AsUTF8Unsafe +-FilePathWatcherTest.DeleteAndRecreate +-FilePathWatcherTest.DeletedFile +-FilePathWatcherTest.DeleteDuringNotify +-FilePathWatcherTest.DirectoryChain +-FilePathWatcherTest.DisappearingDirectory +-FilePathWatcherTest.FileAttributesChanged +-FilePathWatcherTest.ModifiedFile +-FilePathWatcherTest.MoveChild +-FilePathWatcherTest.MovedFile +-FilePathWatcherTest.MoveParent +-FilePathWatcherTest.MultipleWatchersSingleFile +-FilePathWatcherTest.NewFile +-FilePathWatcherTest.NonExistentDirectory +-FilePathWatcherTest.RecursiveWatch +-FilePathWatcherTest.WatchDirectory +-FilePersistentMemoryAllocatorTest.AcceptableTest +-FilePersistentMemoryAllocatorTest.CreationTest +-FilePersistentMemoryAllocatorTest.ExtendTest +-FileProxyTest.SetTimes +-FileTest.Append +-FileUtilProxyTest.Touch +-FileUtilTest.AppendToFile +-FileUtilTest.ChangeDirectoryPermissionsAndEnumerate +-FileUtilTest.ChangeFilePermissionsAndRead +-FileUtilTest.ChangeFilePermissionsAndWrite +-FileUtilTest.CopyDirectoryACL +-FileUtilTest.CopyDirectoryExists +-FileUtilTest.CopyDirectoryNew +-FileUtilTest.CopyDirectoryRecursivelyExists +-FileUtilTest.CopyDirectoryRecursivelyNew +-FileUtilTest.CopyDirectoryWithTrailingSeparators +-FileUtilTest.CopyFileACL +-FileUtilTest.CreateAndReadSymlinks +-FileUtilTest.CreateDirectoryTest +-FileUtilTest.DeleteDirRecursive +-FileUtilTest.DeleteSymlinkToExistentFile +-FileUtilTest.DeleteSymlinkToNonExistentFile +-FileUtilTest.DetectDirectoryTest +-FileUtilTest.ExecutableExistsInPath +-FileUtilTest.FileAndDirectorySize +-FileUtilTest.FileEnumeratorTest +-FileUtilTest.FileToFILE +-FileUtilTest.IsDirectoryEmpty +-FileUtilTest.NormalizeFilePathSymlinks +-FileUtilTest.ReadFile +-FileUtilTest.ReadFileToString +-FileUtilTest.SetCloseOnExec +-FileUtilTest.SetNonBlocking +-FileUtilTest.TouchFile +-HeapDumpWriterTest.BacktraceIndex +-HeapDumpWriterTest.TypeId +-LoggingTest.CheckCausesDistinctBreakpoints +-MemoryMappedFileTest.ExtendableFile +-MemoryMappedFileTest.MapLargePartialRegionInTheMiddle +-MemoryMappedFileTest.MapPartialRegionAtBeginning +-MemoryMappedFileTest.MapPartialRegionAtEnd +-MemoryMappedFileTest.MapSmallFile +-MemoryMappedFileTest.MapSmallPartialRegionInTheMiddle +-MemoryMappedFileTest.MapWholeFileByFD +-MemoryMappedFileTest.MapWholeFileByPath +-MemoryMappedFileTest.MapWholeFileUsingRegion +-MemoryMappedFileTest.WriteableFile +-MessageLoopForIOOnMainThread/FileDescriptorWatcherTest.WatchReadableOneByte/0 +-MessageLoopForIOOnMainThread/FileDescriptorWatcherTest.WatchReadableTwoBytes/0 +-MessageLoopForIOOnMainThread/FileDescriptorWatcherTest.WatchWritable/0 +-MessageLoopTest.FileDescriptorWatcherDoubleStop +-MessageLoopTest.FileDescriptorWatcherOutlivesMessageLoop +-NativeLibraryTest.LoadLibrary +-NativeLibraryTest.LoadLibraryPreferOwnSymbols +-ObserverListThreadSafeTest.AddObserverFromNotificationNotifyAll +-ObserverListThreadSafeTest.CrossThreadNotifications +-ObserverListThreadSafeTest.Existing +-ObserverListThreadSafeTest.NotificationOnValidSequence +-ObserverListThreadSafeTest.OutlivesMessageLoop +-ObserverListThreadSafeTest.RemoveWhileNotificationIsRunning +-OptionalTest.CopyConstructor +-OptionalTest.DefaultConstructor +-OptionalTest.MoveConstructor +-OptionalTest.ValueConstructor +-PartitionAllocTest.Basic +-PartitionAllocTest.DumpMemoryStats +-PartitionAllocTest.FreeCache +-PartitionAllocTest.FreePageListPageTransitions +-PartitionAllocTest.GenericAlloc +-PartitionAllocTest.GenericAllocGetSize +-PartitionAllocTest.GenericAllocSizes +-PartitionAllocTest.LostFreePagesBug +-PartitionAllocTest.MappingCollision +-PartitionAllocTest.MultiAlloc +-PartitionAllocTest.MultiPageAllocs +-PartitionAllocTest.MultiPages +-PartitionAllocTest.PageRefilling +-PartitionAllocTest.PageTransitions +-PartitionAllocTest.PartialPageFreelists +-PartitionAllocTest.PartialPages +-PartitionAllocTest.PreferActiveOverEmpty +-PartitionAllocTest.Purge +-PartitionAllocTest.PurgeDiscardable +-PartitionAllocTest.Realloc +-PartitionAllocTest.ReallocMovesCookies +-PathServiceTest.Get +-PersistentHistogramAllocatorTest.CreateSpareFile +-PersistentHistogramAllocatorTest.CreateWithFile +-PersistentHistogramAllocatorTest.RangesDeDuplication +-PersistentHistogramAllocatorTest.StatisticsRecorderMerge +-PersistentMemoryAllocatorTest.AllocateAndIterate +-PersistentMemoryAllocatorTest.IteratorParallelismTest +-PersistentMemoryAllocatorTest.PageTest +-PersistentMemoryAllocatorTest.ParallelismTest +-PersistentSampleMapTest.Accumulate_LargeValuesDontOverflow +-PersistentSampleMapTest.AccumulateTest +-PlatformThreadTest.ThreadPriorityCurrentThread +-ProcessMemoryDumpTest.CountResidentBytes +-ProcessTest.Move +-ProcessTest.Terminate +-ProcessTest.TerminateCurrentProcessImmediatelyWithNonZeroExitCode +-ProcessTest.TerminateCurrentProcessImmediatelyWithZeroExitCode +-ProcessTest.WaitForExitWithTimeout +-ProcessUtilTest.CurrentDirectory +-ProcessUtilTest.DelayedTermination +-ProcessUtilTest.FDRemapping +-ProcessUtilTest.GetAppOutput +-ProcessUtilTest.GetAppOutputWithExitCode +-ProcessUtilTest.GetTerminationStatusCrash +-ProcessUtilTest.GetTerminationStatusSigKill +-ProcessUtilTest.GetTerminationStatusSigTerm +-ProcessUtilTest.ImmediateTermination +-ProcessUtilTest.KillSlowChild +-ProcessUtilTest.LaunchProcess +-ProcessUtilTest.PreExecHook +-ProcessUtilTest.SpawnChild +-RedirectionToTaskScheduler/SequencedWorkerPoolTest.AvoidsDeadlockOnShutdownWithSequencedBlockingTasks/0 +-RedirectionToTaskScheduler/SequencedWorkerPoolTest.FlushForTesting/0 +-RedirectionToTaskScheduler/SequencedWorkerPoolTest.GetWorkerPoolAndSequenceTokenForCurrentThread/0 +-RedirectionToTaskScheduler/SequencedWorkerPoolTest.ShutsDownCleanWithContinueOnShutdown/0 +-RTLTest.WrapPathWithLTRFormatting +-SafeNumerics.SignedIntegerMath +-SharedMemoryProcessTest.SharedMemoryAcrossProcesses +-SharedMemoryTest.AnonymousExecutable +-SharedMemoryTest.AnonymousPrivate +-SharedMemoryTest.CloseNoUnmap +-SharedMemoryTest.GetReadOnlyHandle +-SharedMemoryTest.MapAt +-SharedMemoryTest.MapMinimumAlignment +-SharedMemoryTest.MapTwice +-SharedMemoryTest.MultipleThreads +-SharedMemoryTest.OpenClose +-SharedMemoryTest.OpenExclusive +-SharedMemoryTest.ShareToSelf +-SharedPersistentMemoryAllocatorTest.CreationTest +-SyncSocket.ClonedSendReceivePeek +-SyncSocket.NormalSendReceivePeek +-SysInfoTest.AmountOfFreeDiskSpace +-SysInfoTest.AmountOfMem +-SysInfoTest.AmountOfTotalDiskSpace +-TraceEventTestFixture.TestTraceFlush +-TrackedObjectsTest.ReuseRetiredThreadData +-TrackedTimeTest.TrackedTimerDuration +-VerifyPathControlledByUserTest.BadPaths +-VerifyPathControlledByUserTest.GroupWriteTest +-VerifyPathControlledByUserTest.OwnershipChecks +-VerifyPathControlledByUserTest.Symlinks +-VerifyPathControlledByUserTest.WriteBitChecks
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 0fb3b19..83e10db 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -708,10 +708,6 @@ "label": "//mojo/common:mojo_common_unittests", "type": "console_test_launcher", }, - "mojo_js_integration_tests": { - "label": "//mojo/edk/js/tests:mojo_js_integration_tests", - "type": "console_test_launcher", - }, "mojo_js_unittests": { "label": "//mojo/edk/js/tests:mojo_js_unittests", "type": "console_test_launcher",
diff --git a/third_party/WebKit/LayoutTests/SmokeTests b/third_party/WebKit/LayoutTests/SmokeTests index 7aa6bb2..05f133bc 100644 --- a/third_party/WebKit/LayoutTests/SmokeTests +++ b/third_party/WebKit/LayoutTests/SmokeTests
@@ -361,7 +361,7 @@ external/wpt/workers/Worker_dispatchEvent_ErrorEvent.htm external/wpt/XMLHttpRequest/event-load.htm external/wpt/XMLHttpRequest/open-after-abort.htm -fast/alignment/new-alignment-values-invalid-if-grid-not-enabled.html +fast/alignment/new-alignment-values.html fast/animation/request-animation-frame-callback-id.html fast/animation/request-animation-frame-cancel.html fast/animation/request-animation-frame-within-callback.html
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flexbox-lines-must-be-stretched-by-default.html b/third_party/WebKit/LayoutTests/css3/flexbox/flexbox-lines-must-be-stretched-by-default.html index 1cff600a..c34127e 100644 --- a/third_party/WebKit/LayoutTests/css3/flexbox/flexbox-lines-must-be-stretched-by-default.html +++ b/third_party/WebKit/LayoutTests/css3/flexbox/flexbox-lines-must-be-stretched-by-default.html
@@ -23,43 +23,28 @@ <script src="../../resources/check-layout-th.js"></script> <body> <script> -function runTest(gridEnabled) -{ - if (window.internals) - internals.runtimeFlags.cssGridLayoutEnabled = gridEnabled; +var flexContainer = document.createElement("div"); +flexContainer.className = "flex-container"; +document.body.appendChild(flexContainer); - var flexContainer = document.createElement("div"); - if (gridEnabled) - flexContainer.className += "gridEnabled flex-container"; - else - flexContainer.className += "gridDisabled flex-container"; - document.body.appendChild(flexContainer); +var flexItem1 = document.createElement("div"); +flexItem1.id = "flexItem1"; +flexItem1.className += "flex-item1"; +flexItem1.setAttribute("data-expected-height", "51"); +flexContainer.appendChild(flexItem1); - var flexItem1 = document.createElement("div"); - flexItem1.id = "flexItem1"; - flexItem1.className += "flex-item1"; - flexItem1.setAttribute("data-expected-height", "51"); - flexContainer.appendChild(flexItem1); +var flexItem2 = document.createElement("div"); +flexItem2.id = "flexItem2"; +flexItem2.className += "flex-item2"; +flexItem2.setAttribute("data-expected-height", "49"); +flexContainer.appendChild(flexItem2); - var flexItem2 = document.createElement("div"); - flexItem2.id = "flexItem2"; - flexItem2.className += "flex-item2"; - flexItem2.setAttribute("data-expected-height", "49"); - flexContainer.appendChild(flexItem2); +var br = document.createElement("br"); +document.body.appendChild(br); - var br = document.createElement("br"); - document.body.appendChild(br); +flexContainer.style.alignContent = "initial"; - flexContainer.style.alignContent = "initial"; - - if (gridEnabled) - checkLayout('.gridEnabled'); - else - checkLayout('.gridDisabled'); -} - -runTest(false); -runTest(true); +checkLayout('.flex-container'); </script> <p>'Test for BUG=647694 - align-content "stretch" is not applied by default when grid is disabled.'</p> <div id="log"></div>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 152ce22c..e4ac01b 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -52625,6 +52625,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01a.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01a.html", @@ -62984,6 +62996,66 @@ {} ] ], + "2dcontext/tools/LICENSE.txt": [ + [ + {} + ] + ], + "2dcontext/tools/build.sh": [ + [ + {} + ] + ], + "2dcontext/tools/current-work-canvas.xhtml": [ + [ + {} + ] + ], + "2dcontext/tools/gentest.py": [ + [ + {} + ] + ], + "2dcontext/tools/gentestutils.py": [ + [ + {} + ] + ], + "2dcontext/tools/name2dir.yaml": [ + [ + {} + ] + ], + "2dcontext/tools/spec.yaml": [ + [ + {} + ] + ], + "2dcontext/tools/specextract.py": [ + [ + {} + ] + ], + "2dcontext/tools/templates.yaml": [ + [ + {} + ] + ], + "2dcontext/tools/tests.yaml": [ + [ + {} + ] + ], + "2dcontext/tools/tests2d.yaml": [ + [ + {} + ] + ], + "2dcontext/tools/tests2dtext.yaml": [ + [ + {} + ] + ], "2dcontext/transformations/.gitkeep": [ [ {} @@ -63419,6 +63491,11 @@ {} ] ], + "WebCryptoAPI/tools/generate.py": [ + [ + {} + ] + ], "WebCryptoAPI/util/helpers.js": [ [ {} @@ -64039,6 +64116,16 @@ {} ] ], + "assumptions/tools/ahem-generate-table.py": [ + [ + {} + ] + ], + "assumptions/tools/build.sh": [ + [ + {} + ] + ], "background-fetch/interfaces-expected.txt": [ [ {} @@ -71489,6 +71576,31 @@ {} ] ], + "css/css-rhythm-1/tools/generators/.gitignore": [ + [ + {} + ] + ], + "css/css-rhythm-1/tools/generators/README.md": [ + [ + {} + ] + ], + "css/css-rhythm-1/tools/generators/gulpfile.js": [ + [ + {} + ] + ], + "css/css-rhythm-1/tools/generators/package.json": [ + [ + {} + ] + ], + "css/css-rhythm-1/tools/generators/snap-width.ejs": [ + [ + {} + ] + ], "css/css-scoping-1/reference/green-box.html": [ [ {} @@ -78349,6 +78461,66 @@ {} ] ], + "css/css-writing-modes-3/tools/generators/.gitignore": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/README.md": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/gulpfile.js": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/orthogonal-parent-shrink-to-fit.ejs": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/package.json": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/text-orientation-generator.js": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/text-orientation-ref.ejs": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/text-orientation-script.ejs": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/ucd/Blocks.txt": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/ucd/DerivedGeneralCategory.txt": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/ucd/VerticalOrientation-16.txt": [ + [ + {} + ] + ], + "css/css-writing-modes-3/tools/generators/unicode-data.js": [ + [ + {} + ] + ], "css/css-writing-modes-3/vertical-alignment-002-ref.xht": [ [ {} @@ -78769,11 +78941,6 @@ {} ] ], - "css/geometry-1/DOMMatrix-stringifier-expected.txt": [ - [ - {} - ] - ], "css/geometry-1/DOMMatrixInit-validate-fixup-expected.txt": [ [ {} @@ -78789,11 +78956,6 @@ {} ] ], - "css/geometry-1/WebKitCSSMatrix-expected.txt": [ - [ - {} - ] - ], "css/geometry-1/historical-expected.txt": [ [ {} @@ -79874,6 +80036,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01-ref.html": [ [ {} @@ -90974,6 +91141,11 @@ {} ] ], + "html/rendering/replaced-elements/tools/gen-svgsizing-tests.py": [ + [ + {} + ] + ], "html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/.gitkeep": [ [ {} @@ -92754,6 +92926,16 @@ {} ] ], + "html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js": [ + [ + {} + ] + ], + "html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js": [ + [ + {} + ] + ], "html/semantics/scripting-1/the-script-element/module/syntaxerror-nested.js": [ [ {} @@ -93864,6 +94046,26 @@ {} ] ], + "html/tools/build.sh": [ + [ + {} + ] + ], + "html/tools/html5lib_test.xml": [ + [ + {} + ] + ], + "html/tools/html5lib_test_fragment.xml": [ + [ + {} + ] + ], + "html/tools/update_html5lib_tests.py": [ + [ + {} + ] + ], "html/webappapis/.gitkeep": [ [ {} @@ -95669,6 +95871,36 @@ {} ] ], + "mixed-content/generic/tools/__init__.py": [ + [ + {} + ] + ], + "mixed-content/generic/tools/clean.py": [ + [ + {} + ] + ], + "mixed-content/generic/tools/common_paths.py": [ + [ + {} + ] + ], + "mixed-content/generic/tools/generate.py": [ + [ + {} + ] + ], + "mixed-content/generic/tools/regenerate": [ + [ + {} + ] + ], + "mixed-content/generic/tools/spec_validator.py": [ + [ + {} + ] + ], "mixed-content/generic/worker.js": [ [ {} @@ -96214,6 +96446,31 @@ {} ] ], + "offscreen-canvas/tools/build.sh": [ + [ + {} + ] + ], + "offscreen-canvas/tools/gentest.py": [ + [ + {} + ] + ], + "offscreen-canvas/tools/name2dir.yaml": [ + [ + {} + ] + ], + "offscreen-canvas/tools/templates.yaml": [ + [ + {} + ] + ], + "offscreen-canvas/tools/tests2d.yaml": [ + [ + {} + ] + ], "orientation-event/OWNERS": [ [ {} @@ -96659,6 +96916,36 @@ {} ] ], + "referrer-policy/generic/tools/__init__.py": [ + [ + {} + ] + ], + "referrer-policy/generic/tools/clean.py": [ + [ + {} + ] + ], + "referrer-policy/generic/tools/common_paths.py": [ + [ + {} + ] + ], + "referrer-policy/generic/tools/generate.py": [ + [ + {} + ] + ], + "referrer-policy/generic/tools/regenerate": [ + [ + {} + ] + ], + "referrer-policy/generic/tools/spec_validator.py": [ + [ + {} + ] + ], "referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-http/fetch-request/insecure-protocol.keep-origin-redirect.http.html.headers": [ [ {} @@ -100889,6 +101176,11 @@ {} ] ], + "service-workers/tools/blink-import.py": [ + [ + {} + ] + ], "shadow-dom/Document-prototype-currentScript-expected.txt": [ [ {} @@ -101419,6 +101711,16 @@ {} ] ], + "subresource-integrity/tools/generate_javascript.py": [ + [ + {} + ] + ], + "subresource-integrity/tools/list_hashes.py": [ + [ + {} + ] + ], "svg-aam/README.md": [ [ {} @@ -103524,6 +103826,21 @@ {} ] ], + "webvtt/parsing/file-parsing/tools/build.py": [ + [ + {} + ] + ], + "webvtt/parsing/file-parsing/tools/parser.py": [ + [ + {} + ] + ], + "webvtt/parsing/file-parsing/tools/spec_report.py": [ + [ + {} + ] + ], "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up-ref.html": [ [ {} @@ -105024,6 +105341,11 @@ {} ] ], + "webvtt/tools/categorize_results.py": [ + [ + {} + ] + ], "workers/OWNERS": [ [ {} @@ -130397,6 +130719,12 @@ {} ] ], + "html/semantics/scripting-1/the-script-element/module/slow-cycle.html": [ + [ + "/html/semantics/scripting-1/the-script-element/module/slow-cycle.html", + {} + ] + ], "html/semantics/scripting-1/the-script-element/module/specifier-error.html": [ [ "/html/semantics/scripting-1/the-script-element/module/specifier-error.html", @@ -167990,6 +168318,54 @@ "8d427c1edbd200cdc77a28945eba7a6a766b2104", "reftest" ], + "2dcontext/tools/LICENSE.txt": [ + "f0866a8c60bf7016987deeb329da99d619eee4f1", + "support" + ], + "2dcontext/tools/build.sh": [ + "e4f65db6a439972ed7a83f4cc2c9bae792ec2d27", + "support" + ], + "2dcontext/tools/current-work-canvas.xhtml": [ + "891246c4dfe34f9b43b5e642b058072c4d664817", + "support" + ], + "2dcontext/tools/gentest.py": [ + "49951605ab640deeb16f2b0aebf2396237fc727e", + "support" + ], + "2dcontext/tools/gentestutils.py": [ + "61b25e0406addab477dc133edf87f25052be8a63", + "support" + ], + "2dcontext/tools/name2dir.yaml": [ + "1333578a501fec686bc7ed22edf4cc8e7203ae13", + "support" + ], + "2dcontext/tools/spec.yaml": [ + "4405a99f9fa29069670a1fb8aaef5e1c89ac33d0", + "support" + ], + "2dcontext/tools/specextract.py": [ + "c6c58223012640480eb1e7d0b9ce4c343cafdb7c", + "support" + ], + "2dcontext/tools/templates.yaml": [ + "343f3ef053fadbb9e6a841d0244a737065f9e208", + "support" + ], + "2dcontext/tools/tests.yaml": [ + "8d5dfd4ca705fa4051b2fd0e6d12bd963a2a2330", + "support" + ], + "2dcontext/tools/tests2d.yaml": [ + "ec014d7d44955c771414aa70748cabdcf48b3a2b", + "support" + ], + "2dcontext/tools/tests2dtext.yaml": [ + "67b14fc993eb652d87c7a282dd6582d459e7f800", + "support" + ], "2dcontext/transformations/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" @@ -170274,6 +170650,10 @@ "408e1a081caa23f7e717128e94eb5cfeae9bac30", "testharness" ], + "WebCryptoAPI/tools/generate.py": [ + "e7b1269e1b432d017256eb200540c7fabeadff25", + "support" + ], "WebCryptoAPI/util/helpers.js": [ "76bfa10171fb405f321d015b4394a2a929d587dd", "support" @@ -171758,6 +172138,14 @@ "df47a9a9342da260175776c3406856be096d0012", "reftest" ], + "assumptions/tools/ahem-generate-table.py": [ + "ed433a26632138f063bbb6093b7f1850e0769c36", + "support" + ], + "assumptions/tools/build.sh": [ + "e7549e915a809b48cac816dacdd7a9bbf476b596", + "support" + ], "background-fetch/interfaces-expected.txt": [ "19fa33f3051ab724d8d6bf3439feb459cfaec9ec", "support" @@ -190174,6 +190562,26 @@ "3660f64d1cc081596b9aa472001970bebbe0a0da", "support" ], + "css/css-rhythm-1/tools/generators/.gitignore": [ + "8b894ec0b3bbc33011392ad9bafeb1df2634db45", + "support" + ], + "css/css-rhythm-1/tools/generators/README.md": [ + "e2bbdf3461247e4dc305f84945a593c3b62dd8b4", + "support" + ], + "css/css-rhythm-1/tools/generators/gulpfile.js": [ + "46f2ca361ad8c456620e7e5c43e65e2923e8bd5c", + "support" + ], + "css/css-rhythm-1/tools/generators/package.json": [ + "79cf7c724e2c8105602f2719b3dec67d7aea49ba", + "support" + ], + "css/css-rhythm-1/tools/generators/snap-width.ejs": [ + "dd031c971a3d11b66cf824c151776eefc3cfde21", + "support" + ], "css/css-scoping-1/css-scoping-shadow-assigned-node-with-before-after.html": [ "85c525233e98f69e6da1f8d25270d16ce0555dd8", "reftest" @@ -204130,6 +204538,54 @@ "47a4aeecb4971b3ddd9589465c868fa71096ce93", "visual" ], + "css/css-writing-modes-3/tools/generators/.gitignore": [ + "8b894ec0b3bbc33011392ad9bafeb1df2634db45", + "support" + ], + "css/css-writing-modes-3/tools/generators/README.md": [ + "bb8dc58366d520524d28fa550b6f51e5c1a06a7a", + "support" + ], + "css/css-writing-modes-3/tools/generators/gulpfile.js": [ + "d2f0b2cb5a2dc87b1715a2440a5c6ab3e068386d", + "support" + ], + "css/css-writing-modes-3/tools/generators/orthogonal-parent-shrink-to-fit.ejs": [ + "a7400b5fd3de25495f570566fd98ff0d6aa01753", + "support" + ], + "css/css-writing-modes-3/tools/generators/package.json": [ + "043456b0bcb4213264ffa553d8d947634db8d8a9", + "support" + ], + "css/css-writing-modes-3/tools/generators/text-orientation-generator.js": [ + "29814715774314c527deb6897ce94911c827de92", + "support" + ], + "css/css-writing-modes-3/tools/generators/text-orientation-ref.ejs": [ + "3469e9e36d2c36dbd726e23e3692c52e19f94539", + "support" + ], + "css/css-writing-modes-3/tools/generators/text-orientation-script.ejs": [ + "b599ae62a388ecdeeabd1a8167c26cae66b6fb46", + "support" + ], + "css/css-writing-modes-3/tools/generators/ucd/Blocks.txt": [ + "59e40360e460eb496cb8e3db3217a01a63e5faa4", + "support" + ], + "css/css-writing-modes-3/tools/generators/ucd/DerivedGeneralCategory.txt": [ + "64f7b671e82f7604cded787112c629df83aaaa99", + "support" + ], + "css/css-writing-modes-3/tools/generators/ucd/VerticalOrientation-16.txt": [ + "1447e4253eb776224ae991b2242dbc1746a59aaf", + "support" + ], + "css/css-writing-modes-3/tools/generators/unicode-data.js": [ + "4d0d0734df208147f8cbf1fd3714bdb28a1a9ff5", + "support" + ], "css/css-writing-modes-3/underline-font-size-vlr-003.xht": [ "6ebc3c3fc822319472f93b736aca59eaf6e9d95d", "visual" @@ -204694,10 +205150,6 @@ "44764bc9b2a59045830fcc1bcedceaf4c2034dcb", "testharness" ], - "css/geometry-1/DOMMatrix-stringifier-expected.txt": [ - "2c24707b18aac4b44848c447df4807417ae452a3", - "support" - ], "css/geometry-1/DOMMatrix-stringifier.html": [ "fbcaa50f5daab1a11325cbbd46e10c524a1f6f80", "testharness" @@ -204738,10 +205190,6 @@ "f24895dc1d994388c45fb6fa39132a7e1c03d18b", "testharness" ], - "css/geometry-1/WebKitCSSMatrix-expected.txt": [ - "527d5a10996c41ba372e3353b75297aa64a4044a", - "support" - ], "css/geometry-1/WebKitCSSMatrix.html": [ "353fb5d2950784a88ce7764bb23c4267ac837ca8", "testharness" @@ -206446,6 +206894,14 @@ "cca1f69024262abd003a75ad4f8182b12d7f364f", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html": [ + "e071deedf049f09776c8948daec3ae760cce9561", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html": [ + "52e8738ca9bdb4e76f835f2c1c51e9882edddb95", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/dir-style-01-ref.html": [ "c81743c7dc2f213973ebeb9f3b8cd9850ab129f1", "support" @@ -210483,7 +210939,7 @@ "testharness" ], "editing/run/forwarddelete-expected.txt": [ - "6c39317abcb1aea04251ac8c16a78ffd3509909b", + "6925482953d8f3b990eaf1077cba4c32c6ade205", "support" ], "editing/run/forwarddelete.html": [ @@ -210555,7 +211011,7 @@ "testharness" ], "editing/run/inserttext-expected.txt": [ - "80987301db3e09deb030c045e225bd250bb59ad1", + "d8a4dd9c00fd873e58ee78eeed3a4d294e19a923", "support" ], "editing/run/inserttext.html": [ @@ -222686,6 +223142,10 @@ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "html/rendering/replaced-elements/tools/gen-svgsizing-tests.py": [ + "c7e3954f1f5c23d74b1758b40eec0701df4a9d0f", + "support" + ], "html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" @@ -225858,6 +226318,18 @@ "36fdeb10e157db42895dd3ed0337eb5c1f311ae8", "testharness" ], + "html/semantics/scripting-1/the-script-element/module/slow-cycle.html": [ + "12b7e271beb788b5cb197f797ff9ea39284da32e", + "testharness" + ], + "html/semantics/scripting-1/the-script-element/module/slow-module-graph-a.js": [ + "790ded4fa1b111b3a1e445f897000bb84f67bf08", + "support" + ], + "html/semantics/scripting-1/the-script-element/module/slow-module-graph-b.js": [ + "0563272baa7fd69ab7a05be44e7f195cd65cab9f", + "support" + ], "html/semantics/scripting-1/the-script-element/module/specifier-error.html": [ "ab17328119bf2b495b7e078233a68cccfd9ead39", "testharness" @@ -225891,7 +226363,7 @@ "testharness" ], "html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html": [ - "6ef870db74ba0dbb6171c74437a78cef4a6f6062", + "19fe5862149465a52c6437e12535c6febdac2324", "testharness" ], "html/semantics/scripting-1/the-script-element/nomodule-set-on-external-module-script.html": [ @@ -225907,7 +226379,7 @@ "testharness" ], "html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html": [ - "a5600b1fcb40e3dbdf223fbeee40c0a3f096eed1", + "4ce8a4cf095d43c542aa8cbcdfd57c5cf381a97b", "testharness" ], "html/semantics/scripting-1/the-script-element/resources/cocoa-module.js": [ @@ -227678,6 +228150,22 @@ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "html/tools/build.sh": [ + "a1c84e96bdd1719cc57f72343eff80783e7eca73", + "support" + ], + "html/tools/html5lib_test.xml": [ + "f352daa7435850cd4cd48b84afc3c03f40882cb5", + "support" + ], + "html/tools/html5lib_test_fragment.xml": [ + "99484d23f37fe2e9bd7fa57efffd4d22373aaeaa", + "support" + ], + "html/tools/update_html5lib_tests.py": [ + "c475456acdd1883f03fd044b34b7af2bbaa09a7c", + "support" + ], "html/webappapis/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" @@ -230986,6 +231474,30 @@ "5c11ec4355d351f608adb189b6b1121073210ed4", "support" ], + "mixed-content/generic/tools/__init__.py": [ + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "support" + ], + "mixed-content/generic/tools/clean.py": [ + "bd717c730c1edc9711a7429cf8827b8a4ba881c3", + "support" + ], + "mixed-content/generic/tools/common_paths.py": [ + "00eb1a2df18ee12da9ce8e145833221f6ed880bc", + "support" + ], + "mixed-content/generic/tools/generate.py": [ + "c5e384d4d778bcd887844395429cced9fb778ff1", + "support" + ], + "mixed-content/generic/tools/regenerate": [ + "d21629058407b1d734417990e1af2663405c6b7d", + "support" + ], + "mixed-content/generic/tools/spec_validator.py": [ + "b0bc2fc11415034f5c31c70f7eb8506a3f0d44bc", + "support" + ], "mixed-content/generic/worker.js": [ "6a0548ef4b906e539d89940aa791a78bba905262", "support" @@ -237574,6 +238086,26 @@ "bf2ff60a9730540a913b8008cb1d8d3a30e1998c", "testharness" ], + "offscreen-canvas/tools/build.sh": [ + "e4f65db6a439972ed7a83f4cc2c9bae792ec2d27", + "support" + ], + "offscreen-canvas/tools/gentest.py": [ + "a00789037db0edb16dac99f4bbfeaaebb5edfdc5", + "support" + ], + "offscreen-canvas/tools/name2dir.yaml": [ + "ed640afbc6614fa9b53e6061192544b0fdc4f51e", + "support" + ], + "offscreen-canvas/tools/templates.yaml": [ + "d8959532cf7948a99fb99b086ed22eb13f1870db", + "support" + ], + "offscreen-canvas/tools/tests2d.yaml": [ + "d2e4f9e53a36426b9d62f9e0969d31a46b88b6b3", + "support" + ], "offscreen-canvas/transformations/2d.transformation.order.html": [ "5d2711b430dbf5822df83d53c034312bacf474b6", "testharness" @@ -239002,6 +239534,30 @@ "383fb3cfa17c4f5cd42512a654e68c68bb9cc5ca", "support" ], + "referrer-policy/generic/tools/__init__.py": [ + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "support" + ], + "referrer-policy/generic/tools/clean.py": [ + "e793013065d7909147d24dc916c0d2aa2f90c37c", + "support" + ], + "referrer-policy/generic/tools/common_paths.py": [ + "420a8c7d279f37efc5e812fdc6303eb4a9709ff1", + "support" + ], + "referrer-policy/generic/tools/generate.py": [ + "e8583441fa8af8d9a915d9b1289eec1965d211bd", + "support" + ], + "referrer-policy/generic/tools/regenerate": [ + "d21629058407b1d734417990e1af2663405c6b7d", + "support" + ], + "referrer-policy/generic/tools/spec_validator.py": [ + "11f613f01201f5ab73d38c400b78354a42b7c9d6", + "support" + ], "referrer-policy/generic/unsupported-csp-referrer-directive.html": [ "31f6bbe5c3320e2338dae74e85aff31e714fec2c", "testharness" @@ -246255,7 +246811,7 @@ "testharness" ], "remote-playback/README.md": [ - "f76a7ece018ba65d920c5df4b6e287521254399f", + "ec6bc4453c4f187bd0640195a912a364955f6569", "support" ], "remote-playback/cancel-watch-availability.html": [ @@ -248994,6 +249550,10 @@ "286b618cdad57d95201c3668d0724d37734058dd", "stub" ], + "service-workers/tools/blink-import.py": [ + "d76057125f84da8c17e1677a25f9009078a5085b", + "support" + ], "shadow-dom/Document-prototype-adoptNode.html": [ "073a718d72ebc7cc4c0564a4526e4ef9c3f604d7", "testharness" @@ -250454,6 +251014,14 @@ "74d5ee47bc3cb52208c82da1304fbb3b6cd51560", "testharness" ], + "subresource-integrity/tools/generate_javascript.py": [ + "08e8f4066ad2f5d6b7cdb8e2b81ecfb71f4f61f9", + "support" + ], + "subresource-integrity/tools/list_hashes.py": [ + "a30aed8fd663c8baa7c5b2a116122979f6d80cda", + "support" + ], "svg-aam/README.md": [ "e500c4f877bd2d7b482600d7c6b60823c4d49179", "support" @@ -251107,7 +251675,7 @@ "testharness" ], "url/urltestdata.json": [ - "d52fa5f6c7565eea8e33277a7ad58986b21fc592", + "f6265e6cdc24470a839858d49984713573a66f55", "support" ], "user-timing/clear_all_marks.any.js": [ @@ -254746,6 +255314,18 @@ "ba2fd1a6cb63cdf9887ed9936dfdc1f5a6766057", "testharness" ], + "webvtt/parsing/file-parsing/tools/build.py": [ + "c6dcec4de817a5197bbe13d805aa438cff8de354", + "support" + ], + "webvtt/parsing/file-parsing/tools/parser.py": [ + "fde4864ecfaffd4e6fc26327338bc765518f365e", + "support" + ], + "webvtt/parsing/file-parsing/tools/spec_report.py": [ + "9fcc13d8265190aaf968324bddb8fa5aa255d2eb", + "support" + ], "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up-ref.html": [ "d7be95cbc484a1f9abeb5d00c6b8accd1fc5fe07", "support" @@ -256830,6 +257410,10 @@ "f2372a492268a1b17763a42a808351128128fd89", "reftest" ], + "webvtt/tools/categorize_results.py": [ + "339f3f5f0e968076031f4a7c4361f9dba14d485d", + "support" + ], "workers/OWNERS": [ "b0b1d8b5f995ce1f7aefd1ce9b454b7b398b578f", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/LICENSE.txt b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/LICENSE.txt new file mode 100644 index 0000000..b248aa87 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/LICENSE.txt
@@ -0,0 +1,36 @@ +2DContext and <canvas> test suite + +Copyright (c) 2010 Philip Taylor + +The code and all associated data files may be used under the terms of the +following license: + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of works must retain the original copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the original copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the W3C nor the names of its contributors may be used to + endorse or promote products derived from this work without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Alternatively, the code and data may be used under the terms of +http://www.w3.org/Consortium/Legal/2008/04-testsuite-license.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/build.sh b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/build.sh new file mode 100755 index 0000000..f69fa4f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/build.sh
@@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -ex + +cd "${0%/*}" +virtualenv -p python .virtualenv +.virtualenv/bin/pip install pyyaml cairocffi +.virtualenv/bin/python gentest.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/current-work-canvas.xhtml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/current-work-canvas.xhtml new file mode 100644 index 0000000..b41ad7d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/current-work-canvas.xhtml
@@ -0,0 +1,3693 @@ +<?xml version="1.0" encoding="UTF-8"?><html xml:lang="en-US-x-hixie" xmlns="http://www.w3.org/1999/xhtml"><head><title>HTML Standard</title><link href="http://www.whatwg.org/style/specification" rel="stylesheet"/><link href="http://www.whatwg.org/images/icon" rel="icon"/><style> + .proposal { border: blue solid; padding: 1em; } + .bad, .bad *:not(.XXX) { color: gray; border-color: gray; background: transparent; } + #updatesStatus { display: none; } + #updatesStatus.relevant { display: block; position: fixed; right: 1em; top: 1em; padding: 0.5em; font: bold small sans-serif; min-width: 25em; width: 30%; max-width: 40em; height: auto; border: ridge 4px gray; background: #EEEEEE; color: black; } + div.head .logo { width: 11em; margin-bottom: 20em; } + #configUI { position: absolute; z-index: 20; top: 10em; right: 0; width: 11em; padding: 0 0.5em 0 0.5em; font-size: small; background: gray; background: rgba(32,32,32,0.9); color: white; border-radius: 1em 0 0 1em; -moz-border-radius: 1em 0 0 1em; } + #configUI p { margin: 0.75em 0; padding: 0.3em; } + #configUI p label { display: block; } + #configUI #updateUI, #configUI .loginUI { text-align: center; } + #configUI input[type=button] { display: block; margin: auto; } + #configUI :link, #configUI :visited { color: white; } + #configUI :link:hover, #configUI :visited:hover { background: transparent; } + #reviewer { position: fixed; bottom: 0; right: 0; padding: 0.15em 0.25em 0em 0.5em; white-space: nowrap; overflow: hidden; z-index: 30; background: gray; background: rgba(32,32,32,0.9); color: white; border-radius: 1em 0 0 0; -moz-border-radius: 1em 0 0 0; max-width: 90%; } + #reviewer input { max-width: 50%; } + #reviewer * { font-size: small; } + #reviewer.off > :not(:first-child) { display: none; } + #alert { position: fixed; top: 20%; left: 20%; right: 20%; font-size: 2em; padding: 0.5em; z-index: 40; background: gray; background: rgba(32,32,32,0.9); color: white; border-radius: 1em; -moz-border-radius: 1em; -webkit-transition: opacity 1s linear; } + #alert.closed { opacity: 0; } + #alert button { position: absolute; top: -1em; right: 2em; border-radius: 1em 1em 0 0; border: none; line-height: 0.9; color: white; background: rgb(64,64,64); font-size: 0.6em; font-weight: 900; cursor: pointer; } + #alert :link, #alert :visited { color: white; } + #alert :link:hover, #alert :visited:hover { background: transparent; } + @media print { #configUI { display: none; } } + .rfc2119 { font-variant: small-caps; text-shadow: 0 0 0.5em yellow; position: static; } + .rfc2119::after { position: absolute; left: 0; width: 25px; text-align: center; color: yellow; text-shadow: 0.075em 0.075em 0.2em black; } + .rfc2119.m\ust::after { content: '\2605'; } + .rfc2119.s\hould::after { content: '\2606'; } + [hidden] { display: none; } + </style><style type="text/css"> + + .applies thead th > * { display: block; } + .applies thead code { display: block; } + .applies tbody th { whitespace: nowrap; } + .applies td { text-align: center; } + .applies .yes { background: yellow; } + + .matrix, .matrix td { border: hidden; text-align: right; } + .matrix { margin-left: 2em; } + + .dice-example { border-collapse: collapse; border-style: hidden solid solid hidden; border-width: thin; margin-left: 3em; } + .dice-example caption { width: 30em; font-size: smaller; font-style: italic; padding: 0.75em 0; text-align: left; } + .dice-example td, .dice-example th { border: solid thin; width: 1.35em; height: 1.05em; text-align: center; padding: 0; } + + td.eg { border-width: thin; text-align: center; } + + #table-example-1 { border: solid thin; border-collapse: collapse; margin-left: 3em; } + #table-example-1 * { font-family: "Essays1743", serif; line-height: 1.01em; } + #table-example-1 caption { padding-bottom: 0.5em; } + #table-example-1 thead, #table-example-1 tbody { border: none; } + #table-example-1 th, #table-example-1 td { border: solid thin; } + #table-example-1 th { font-weight: normal; } + #table-example-1 td { border-style: none solid; vertical-align: top; } + #table-example-1 th { padding: 0.5em; vertical-align: middle; text-align: center; } + #table-example-1 tbody tr:first-child td { padding-top: 0.5em; } + #table-example-1 tbody tr:last-child td { padding-bottom: 1.5em; } + #table-example-1 tbody td:first-child { padding-left: 2.5em; padding-right: 0; width: 9em; } + #table-example-1 tbody td:first-child::after { content: leader(". "); } + #table-example-1 tbody td { padding-left: 2em; padding-right: 2em; } + #table-example-1 tbody td:first-child + td { width: 10em; } + #table-example-1 tbody td:first-child + td ~ td { width: 2.5em; } + #table-example-1 tbody td:first-child + td + td + td ~ td { width: 1.25em; } + + .apple-table-examples { border: none; border-collapse: separate; border-spacing: 1.5em 0em; width: 40em; margin-left: 3em; } + .apple-table-examples * { font-family: "Times", serif; } + .apple-table-examples td, .apple-table-examples th { border: none; white-space: nowrap; padding-top: 0; padding-bottom: 0; } + .apple-table-examples tbody th:first-child { border-left: none; width: 100%; } + .apple-table-examples thead th:first-child ~ th { font-size: smaller; font-weight: bolder; border-bottom: solid 2px; text-align: center; } + .apple-table-examples tbody th::after, .apple-table-examples tfoot th::after { content: leader(". ") } + .apple-table-examples tbody th, .apple-table-examples tfoot th { font: inherit; text-align: left; } + .apple-table-examples td { text-align: right; vertical-align: top; } + .apple-table-examples.e1 tbody tr:last-child td { border-bottom: solid 1px; } + .apple-table-examples.e1 tbody + tbody tr:last-child td { border-bottom: double 3px; } + .apple-table-examples.e2 th[scope=row] { padding-left: 1em; } + .apple-table-examples sup { line-height: 0; } + + .details-example img { vertical-align: top; } + + #base64-table { + white-space: nowrap; + font-size: 0.6em; + column-width: 6em; + column-count: 5; + column-gap: 1em; + -moz-column-width: 6em; + -moz-column-count: 5; + -moz-column-gap: 1em; + -webkit-column-width: 6em; + -webkit-column-count: 5; + -webkit-column-gap: 1em; + } + #base64-table thead { display: none; } + #base64-table * { border: none; } + #base64-table tbody td:first-child:after { content: ':'; } + #base64-table tbody td:last-child { text-align: right; } + + #named-character-references-table { + white-space: nowrap; + font-size: 0.6em; + column-width: 30em; + column-gap: 1em; + -moz-column-width: 30em; + -moz-column-gap: 1em; + -webkit-column-width: 30em; + -webkit-column-gap: 1em; + } + #named-character-references-table > table > tbody > tr > td:first-child + td, + #named-character-references-table > table > tbody > tr > td:last-child { text-align: center; } + #named-character-references-table > table > tbody > tr > td:last-child:hover > span { position: absolute; top: auto; left: auto; margin-left: 0.5em; line-height: 1.2; font-size: 5em; border: outset; padding: 0.25em 0.5em; background: white; width: 1.25em; height: auto; text-align: center; } + #named-character-references-table > table > tbody > tr#entity-CounterClockwiseContourIntegral > td:first-child { font-size: 0.5em; } + + .glyph.control { color: red; } + + @font-face { + font-family: 'Essays1743'; + src: url('http://www.whatwg.org/specs/web-apps/current-work/fonts/Essays1743.ttf'); + } + @font-face { + font-family: 'Essays1743'; + font-weight: bold; + src: url('http://www.whatwg.org/specs/web-apps/current-work/fonts/Essays1743-Bold.ttf'); + } + @font-face { + font-family: 'Essays1743'; + font-style: italic; + src: url('http://www.whatwg.org/specs/web-apps/current-work/fonts/Essays1743-Italic.ttf'); + } + @font-face { + font-family: 'Essays1743'; + font-style: italic; + font-weight: bold; + src: url('http://www.whatwg.org/specs/web-apps/current-work/fonts/Essays1743-BoldItalic.ttf'); + } + + </style><style> + .domintro:before { display: table; margin: -1em -0.5em -0.5em auto; width: auto; content: 'This box is non-normative. Implementation requirements are given below this box.'; color: black; font-style: italic; border: solid 2px; background: white; padding: 0 0.25em; } + </style><link href="data:text/css," id="complete" rel="stylesheet" title="Complete specification"/><link href="data:text/css,.impl%20{%20display:%20none;%20}%0Ahtml%20{%20border:%20solid%20yellow;%20}%20.domintro:before%20{%20display:%20none;%20}" id="author" rel="alternate stylesheet" title="Author documentation only"/><link href="data:text/css,.impl%20{%20background:%20%23FFEEEE;%20}%20.domintro:before%20{%20background:%20%23FFEEEE;%20}" id="highlight" rel="alternate stylesheet" title="Highlight implementation requirements"/><link href="http://www.whatwg.org/specs/web-apps/current-work/status.css" rel="stylesheet"/></head><body class="draft" onload="init()"><header class="head" id="head"><p><a class="logo" href="http://www.whatwg.org/"><img alt="WHATWG" height="101" src="http://www.whatwg.org/images/logo" width="101"/></a></p> + <hgroup><h1 class="allcaps">HTML</h1> + <h2 class="no-num no-toc">Living Standard — Last Updated 8 August 2011</h2> + </hgroup><p class="copyright">© Copyright 2004-2011 Apple Computer, Inc., + Mozilla Foundation, and Opera Software ASA.</p> + <p class="copyright">You are granted a license to use, reproduce + and create derivative works of this document.</p> + + </header><h4 id="the-canvas-element"><span class="secno">4.8.11 </span>The <dfn id="canvas"><code>canvas</code></dfn> element</h4> + + <dl class="element"><dt>Categories</dt> + <dd><a href="#flow-content">Flow content</a>.</dd> + <dd><a href="#phrasing-content">Phrasing content</a>.</dd> + <dd><a href="#embedded-content">Embedded content</a>.</dd> + <dt>Contexts in which this element can be used:</dt> + <dd>Where <a href="#embedded-content">embedded content</a> is expected.</dd> + <dt>Content model:</dt> + <dd><a href="#transparent">Transparent</a>.</dd> + <dd><a href="#transparent">Transparent</a><!-- +--><!--FORK--><!-- +-->, but with no <a href="#interactive-content">interactive content</a> descendants except for <code><a href="#the-a-element">a</a></code> elements, <code><a href="#the-button-element">button</a></code> elements, <code><a href="#the-input-element">input</a></code> elements whose <code title="attr-input-type"><a href="#attr-input-type">type</a></code> attribute are in the <a href="#checkbox-state" title="attr-input-type-checkbox">Checkbox</a> or <a href="#radio-button-state" title="attr-input-type-radio">Radio Button</a> states, and <code><a href="#the-input-element">input</a></code> elements that are <a href="#concept-button" title="concept-button">buttons</a><!-- +--><!--FORK--><!-- +-->.</dd> <!-- and maybe <select>, I guess? I've left it in for now, since I guess authors might make accessible selects if they're simple enough, and it's not obvious how to distinguish the simple ones from the complex ones... --> + <dt>Content attributes:</dt> + <dd><a href="#global-attributes">Global attributes</a></dd> + <dd><code title="attr-canvas-width"><a href="#attr-canvas-width">width</a></code></dd> + <dd><code title="attr-canvas-height"><a href="#attr-canvas-height">height</a></code></dd> + <dt>DOM interface:</dt> + <dd> + <pre class="idl">interface <dfn id="htmlcanvaselement">HTMLCanvasElement</dfn> : <a href="#htmlelement">HTMLElement</a> { + attribute unsigned long <a href="#dom-canvas-width" title="dom-canvas-width">width</a>; + attribute unsigned long <a href="#dom-canvas-height" title="dom-canvas-height">height</a>; + + DOMString <a href="#dom-canvas-todataurl" title="dom-canvas-toDataURL">toDataURL</a>(in optional DOMString type, in any... args); + void <a href="#dom-canvas-toblob" title="dom-canvas-toBlob">toBlob</a>(in <span>FileCallback</span>? callback, in optional DOMString type, in any... args); + + object? <a href="#dom-canvas-getcontext" title="dom-canvas-getContext">getContext</a>(in DOMString contextId, in any... args); +};</pre> + </dd> + </dl><p>The <code><a href="#the-canvas-element">canvas</a></code> element provides scripts with a + resolution-dependent bitmap canvas, which can be used for rendering + graphs, game graphics, or other visual images on the fly.</p> + + <p>Authors should not use the <code><a href="#the-canvas-element">canvas</a></code> element in a + document when a more suitable element is available. For example, it + is inappropriate to use a <code><a href="#the-canvas-element">canvas</a></code> element to render a + page heading: if the desired presentation of the heading is + graphically intense, it should be marked up using appropriate + elements (typically <code><a href="#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements">h1</a></code>) and then styled using CSS and + supporting technologies such as XBL.</p> + + <p>When authors use the <code><a href="#the-canvas-element">canvas</a></code> element, they must also + provide content that, when presented to the user, conveys + essentially the same function or purpose as the bitmap canvas. This + content may be placed as content of the <code><a href="#the-canvas-element">canvas</a></code> + element. The contents of the <code><a href="#the-canvas-element">canvas</a></code> element, if any, + are the element's <a href="#fallback-content">fallback content</a>.</p> + + <p>In interactive visual media, if <a href="#concept-n-script" title="concept-n-script">scripting is enabled</a> for the + <code><a href="#the-canvas-element">canvas</a></code> element, and if support for <code><a href="#the-canvas-element">canvas</a></code> + elements has been enabled, the <code><a href="#the-canvas-element">canvas</a></code> element + <a href="#represents">represents</a> <a href="#embedded-content">embedded content</a> consisting of + a dynamically created image.</p> + + <p>In non-interactive, static, visual media, if the + <code><a href="#the-canvas-element">canvas</a></code> element has been previously painted on (e.g. if + the page was viewed in an interactive visual medium and is now being + printed, or if some script that ran during the page layout process + painted on the element), then the <code><a href="#the-canvas-element">canvas</a></code> element + <a href="#represents">represents</a> <a href="#embedded-content">embedded content</a> with the + current image and size. Otherwise, the element represents its + <a href="#fallback-content">fallback content</a> instead.</p> + + <p>In non-visual media, and in visual media if <a href="#concept-n-noscript" title="concept-n-noscript">scripting is disabled</a> for the + <code><a href="#the-canvas-element">canvas</a></code> element or if support for <code><a href="#the-canvas-element">canvas</a></code> + elements has been disabled, the <code><a href="#the-canvas-element">canvas</a></code> element + <a href="#represents">represents</a> its <a href="#fallback-content">fallback content</a> + instead.</p> + + <!-- CANVAS-FOCUS-FALLBACK --> + <p>When a <code><a href="#the-canvas-element">canvas</a></code> element <a href="#represents">represents</a> + <a href="#embedded-content">embedded content</a>, the user can still focus descendants + of the <code><a href="#the-canvas-element">canvas</a></code> element (in the <a href="#fallback-content">fallback + content</a>). When an element is focused, it is the target of + keyboard interaction events (even though the element itself is not + visible). This allows authors to make an interactive canvas + keyboard-accessible: authors should have a one-to-one mapping of + interactive regions to focusable elements in the <a href="#fallback-content">fallback + content</a>. (Focus has no effect on mouse interaction + events.) <a href="#DOMEVENTS">[DOMEVENTS]</a></p> + + <p>The <code><a href="#the-canvas-element">canvas</a></code> element has two attributes to control the + size of the coordinate space: <dfn id="attr-canvas-width" title="attr-canvas-width"><code>width</code></dfn> and <dfn id="attr-canvas-height" title="attr-canvas-height"><code>height</code></dfn>. These + attributes, when specified, must have values that are <a href="#valid-non-negative-integer" title="valid non-negative integer">valid non-negative + integers</a>. <span class="impl">The <a href="#rules-for-parsing-non-negative-integers">rules for parsing + non-negative integers</a> must be used to obtain their numeric + values. If an attribute is missing, or if parsing its value returns + an error, then the default value must be used instead.</span> The + <code title="attr-canvas-width"><a href="#attr-canvas-width">width</a></code> attribute defaults to + 300, and the <code title="attr-canvas-height"><a href="#attr-canvas-height">height</a></code> + attribute defaults to 150.</p> + + <p>The intrinsic dimensions of the <code><a href="#the-canvas-element">canvas</a></code> element equal + the size of the coordinate space, with the numbers interpreted in + CSS pixels. However, the element can be sized arbitrarily by a + style sheet. During rendering, the image is scaled to fit this layout + size.</p> + + <div class="impl"> + + <p>The size of the coordinate space does not necessarily represent + the size of the actual bitmap that the user agent will use + internally or during rendering. On high-definition displays, for + instance, the user agent may internally use a bitmap with two device + pixels per unit in the coordinate space, so that the rendering + remains at high quality throughout.</p> + + <p>When the <code><a href="#the-canvas-element">canvas</a></code> element is created, and subsequently + whenever the <code title="attr-canvas-width"><a href="#attr-canvas-width">width</a></code> and <code title="attr-canvas-height"><a href="#attr-canvas-height">height</a></code> attributes are set (whether + to a new value or to the previous value), the bitmap and any + associated contexts must be cleared back to their initial state and + reinitialized with the newly specified coordinate space + dimensions.</p> + + <p>When the canvas is initialized, its bitmap must be cleared to + transparent black.</p> + + <p>The <dfn id="dom-canvas-width" title="dom-canvas-width"><code>width</code></dfn> and + <dfn id="dom-canvas-height" title="dom-canvas-height"><code>height</code></dfn> IDL + attributes must <a href="#reflect">reflect</a> the respective content + attributes of the same name, with the same defaults.</p> + + </div> + + <div class="example"> + <p>Only one square appears to be drawn in the following example:</p> + <pre> // canvas is a reference to a <canvas> element + var context = canvas.getContext('2d'); + context.fillRect(0,0,50,50); + canvas.setAttribute('width', '300'); // clears the canvas + context.fillRect(0,100,50,50); + canvas.width = canvas.width; // clears the canvas + context.fillRect(100,0,50,50); // only this square remains</pre> + </div> + + <hr/><dl class="domintro"><dt><var title="">context</var> = <var title="">canvas</var> . <code title="dom-canvas-getContext"><a href="#dom-canvas-getcontext">getContext</a></code>(<var title="">contextId</var> [, ... ])</dt> + + <dd> + + <p>Returns an object that exposes an API for drawing on the + canvas. The first argument specifies the desired API. Subsequent + arguments are handled by that API.</p> + +<!--2DCONTEXT--> + + <p>This specification defines the "<code title="canvas-context-2d"><a href="#canvas-context-2d">2d</a></code>" context below. There is also + a specification that defines a "<code title="canvas-context-webgl">webgl</code>" context. <a href="#refsWEBGL">[WEBGL]</a></p> + +<!--2DCONTEXT--> + + <p>The list of defined contexts is given on the <a href="http://wiki.whatwg.org/wiki/CanvasContexts">WHATWG Wiki + CanvasContexts page</a>. <a href="#refsWHATWGWIKI">[WHATWGWIKI]</a> + + </p><p>Returns null if the given context ID is not supported or if the + canvas has already been initialized with some other (incompatible) + context type (e.g. trying to get a "<code title="canvas-context-2d"><a href="#canvas-context-2d">2d</a></code>" context after getting a + "<code title="canvas-context-webgl">webgl</code>" context).</p> + + </dd> + + </dl><div class="impl"> + + <p>A <code><a href="#the-canvas-element">canvas</a></code> element can have a <dfn id="primary-context">primary + context</dfn>, which is the first context to have been obtained for + that element. When created, a <code><a href="#the-canvas-element">canvas</a></code> element must not + have a <a href="#primary-context">primary context</a>.</p> + + + <p>The <dfn id="dom-canvas-getcontext" title="dom-canvas-getContext"><code>getContext(<var title="">contextId</var>, <var title="">args...</var>)</code></dfn> + method of the <code><a href="#the-canvas-element">canvas</a></code> element, when invoked, must run + the following steps:</p> + + <ol><li><p>Let <var title="">contextId</var> be the first argument to + the method.</p></li> + + <li> + + <p>If <var title="">contextId</var> is not the name of a context + supported by the user agent, return null and abort these + steps.</p> + + <p class="note">An example of this would be a user agent that + theoretically supports the "<code title="canvas-context-webgl">webgl</code>" 3D context, in the case + where the platform does not have hardware support for OpenGL and + the user agent does not have a software OpenGL implementation. + Despite the user agent recognising the "<code title="canvas-context-webgl">webgl</code>" name, it would return + null at this step because that context is not, in practice, + supported at the time of the call.</p> + + </li> + + <li><p>If the element has a <a href="#primary-context">primary context</a> and that + context's entry in the <a href="http://wiki.whatwg.org/wiki/CanvasContexts">WHATWG Wiki + CanvasContexts page</a> does not list <var title="">contextId</var> + as a context with which it is compatible, return null and abort + these steps. <a href="#refsWHATWGWIKI">[WHATWGWIKI]</a></p></li> + + <li><p>If the element does not have a <a href="#primary-context">primary context</a>, + let the element's <a href="#primary-context">primary context</a> be <var title="">contextId</var>.</p></li> + + <li><p>If the <code title="dom-canvas-getContext"><a href="#dom-canvas-getcontext">getContext()</a></code> method has + already been invoked on this element for the same <var title="">contextId</var>, return the same object as was returned + that time, and abort these steps. The additional arguments are + ignored.</p></li> + + <li><p><dfn id="getcontext-return" title="getContext-return">Return a new object for <var title="">contextId</var></dfn>, as defined by the specification + given for <var title="">contextId</var>'s entry in the <a href="http://wiki.whatwg.org/wiki/CanvasContexts">WHATWG Wiki + CanvasContexts page</a>. <a href="#refsWHATWGWIKI">[WHATWGWIKI]</a></p></li> + + </ol><p>New context types may be registered in the <a href="http://wiki.whatwg.org/wiki/CanvasContexts">WHATWG Wiki + CanvasContexts page</a>. <a href="#refsWHATWGWIKI">[WHATWGWIKI]</a></p> + + <p>Anyone is free to edit the WHATWG Wiki CanvasContexts page at any + time to add a new context type. These new context types must be + specified with the following information:</p> + + <dl><dt>Keyword</dt> + + <dd><p>The value of <var title="">contextID</var> that will return + the object for the new API.</p></dd> + + + <dt>Specification</dt> + + <dd><p>A link to a formal specification of the context type's + API. It could be another page on the Wiki, or a link to an external + page. If the type does not have a formal specification, an informal + description can be substituted until such time as a formal + specification is available.</p></dd> + + + <dt>Compatible with</dt> + + <dd><p>The list of context types that are compatible with this one + (i.e. that operate on the same underlying bitmap). This list must + be transitive and symmetric; if one context type is defined as + compatible with another, then all types it is compatible with must + be compatible with all types the other is compatible with.</p></dd> + + </dl><p>Vendors may also define experimental contexts using the syntax + <code><var title="">vendorname</var>-<var title="">context</var></code>, for example, + <code>moz-3d</code>. Such contexts should be registered in the + WHATWG Wiki CanvasContexts page.</p> + + </div> + + <hr/><dl class="domintro"><dt><var title="">url</var> = <var title="">canvas</var> . <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL</a></code>( [ <var title="">type</var>, ... ])</dt> + + <dd> + + <p>Returns a <a href="#data-protocol" title="data protocol"><code title="">data:</code> URL</a> for the image in the canvas.</p> + + <p>The first argument, if provided, controls the type of the image + to be returned (e.g. PNG or JPEG). The default is <code title="">image/png</code>; that type is also used if the given + type isn't supported. The other arguments are specific to the + type, and control the way that the image is generated, as given in + the table below.</p> + + <p>When trying to use types other than "<code>image/png</code>", + authors can check if the image was really returned in the + requested format by checking to see if the returned string starts + with one of the exact strings "<code title="">data:image/png,</code>" or "<code title="">data:image/png;</code>". If it does, the image is PNG, + and thus the requested type was not supported. (The one exception + to this is if the canvas has either no height or no width, in + which case the result might simply be "<code title="">data:,</code>".)</p> + + </dd> + + <dt><var title="">canvas</var> . <code title="dom-canvas-toBlob"><a href="#dom-canvas-toblob">toBlob</a></code>(<var title="">callback</var> [, <var title="">type</var>, ... ])</dt> + + <dd> + + <p>Creates a <code><a href="#blob">Blob</a></code> object representing a file + containing the image in the canvas, and invokes a callback with a + handle to that object.</p> + + <p>The second argument, if provided, controls the type of the + image to be returned (e.g. PNG or JPEG). The default is <code title="">image/png</code>; that type is also used if the given + type isn't supported. The other arguments are specific to the + type, and control the way that the image is generated, as given in + the table below.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-canvas-todataurl" title="dom-canvas-toDataURL"><code>toDataURL()</code></dfn> method + must run the following steps:</p> + + <ol><li><p>If the canvas has no pixels (i.e. either its horizontal + dimension or its vertical dimension is zero) then return the string + "<code title="">data:,</code>" and abort these steps. (This is the + shortest <a href="#data-protocol" title="data protocol"><code title="">data:</code> + URL</a>; it represents the empty string in a <code title="">text/plain</code> resource.)</p></li> + + <li><p>Let <var title="">file</var> be <a href="#a-serialization-of-the-image-as-a-file">a serialization of the + image as a file</a>, using the method's arguments (if any) as + the <var title="">arguments</var>.</p></li> + + <li><p>Return a <a href="#data-protocol" title="data protocol"><code title="">data:</code> URL</a> representing <var title="">file</var>. <a href="#refsRFC2397">[RFC2397]</a></p> + + <!-- should we explicitly require the URL to be base64-encoded and + not have any parameters, to ensure the same exact URL is generated + in each browser? --> + + </li></ol><p>The <dfn id="dom-canvas-toblob" title="dom-canvas-toBlob"><code>toBlob()</code></dfn> method + must run the following steps:</p> + + <ol><li><p>Let <var title="">callback</var> be the first + argument.</p></li> + + <li><p>Let <var title="">arguments</var> be the second and + subsequent arguments to the method, if any.</p></li> + + <li><p>Let <var title="">file</var> be <a href="#a-serialization-of-the-image-as-a-file">a serialization of the + image as a file</a>, using <var title="">arguments</var>.</p></li> + + <li><p>Return, but continue running these steps + asynchronously.</p></li> + + <li><p>If <var title="">callback</var> is null, abort these + steps.</p></li> + + <li><p><a href="#queue-a-task">Queue a task</a> to invoke the + <code>FileCallback</code> <var title="">callback</var> with a + <code><a href="#blob">Blob</a></code> object representing <var title="">file</var> as + its argument. The <a href="#task-source">task source</a> for this task is the + <dfn id="canvas-blob-serialization-task-source">canvas blob serialization task source</dfn>. <a href="#refsFILESYSTEMAPI">[FILESYSTEMAPI]</a> <a href="#refsFILEAPI">[FILEAPI]</a> </p></li> + + </ol><p>When a user agent is to create <dfn id="a-serialization-of-the-image-as-a-file">a serialization of the image + as a file</dfn>, optionally with some given <var title="">arguments</var>, it must create an image file in the format + given by the first value of <var title="">arguments</var>, or, if + there are no <var title="">arguments</var>, in the PNG format. <a href="#refsPNG">[PNG]</a></p> + + <p>If <var title="">arguments</var> is not empty, the first value + must be interpreted as a <a href="#mime-type" title="MIME type">MIME type</a> + giving the format to use. If the type has any parameters, it must be + treated as not supported.</p> + + <p class="example">For example, the value "<code>image/png</code>" would + mean to generate a PNG image, the value "<code>image/jpeg</code>" + would mean to generate a JPEG image, and the value + "<code>image/svg+xml</code>" would mean to generate an SVG image + (which would probably require that the implementation actually keep + enough information to reliably render an SVG image from the canvas).</p> + + <p>User agents must support PNG ("<code>image/png</code>"). User + agents may support other types. If the user agent does not support + the requested type, it must create the file using the PNG format. <a href="#refsPNG">[PNG]</a></p> + + <p>User agents must <a href="#converted-to-ascii-lowercase" title="converted to ASCII + lowercase">convert the provided type to ASCII lowercase</a> + before establishing if they support that type.</p> + + <p>For image types that do not support an alpha channel, the + serialized image must be the canvas image composited onto a solid + black background using the source-over operator.</p> + + <p>If the first argument in <var title="">arguments</var> gives a + type corresponding to one of the types given in the first column of + the following table, and the user agent supports that type, then the + subsequent arguments, if any, must be treated as described in the + second cell of that row.</p> + + </div> + + <table><thead><tr><th> Type </th><th> Other arguments </th><th> Reference + </th></tr></thead><tbody><tr><td> <code>image/jpeg</code> + </td><td> The second argument<span class="impl">, if it</span> is a + number in the range 0.0 to 1.0 inclusive<span class="impl">, must + be</span> treated as the desired quality level. <span class="impl">If it is not a number or is outside that range, the + user agent must use its default value, as if the argument had + been omitted.</span> + </td><td> <a href="#refsJPEG">[JPEG]</a> + </td></tr></tbody></table><div class="impl"> + + <p>For the purposes of these rules, an argument is considered to be + a number if it is converted to an IDL double value by the rules for + handling arguments of type <code title="">any</code> in the Web IDL + specification. <a href="#refsWEBIDL">[WEBIDL]</a></p> + + <p>Other arguments must be ignored and must not cause the user agent + to raise an exception. A future version of this specification will + probably define other parameters to be passed to these methods to + allow authors to more carefully control compression settings, image + metadata, etc.</p> + + </div> + + <!--2DCONTEXT--> + + <div data-component="HTML Canvas 2D Context (editor: Ian Hickson)"> + + <h5 id="2dcontext"><span class="secno">4.8.11.1 </span>The 2D context</h5> + + <!-- v2: we're on v4.1. suggestions for next version are marked v5, v6. --> + + + + <p>This specification defines the <dfn id="canvas-context-2d" title="canvas-context-2d"><code>2d</code></dfn> context type, whose + API is implemented using the <code><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> + interface.</p> + + <div class="impl"> + + <p>When the <code title="dom-canvas-getContext"><a href="#dom-canvas-getcontext">getContext()</a></code> + method of a <code><a href="#the-canvas-element">canvas</a></code> element is to <a href="#getcontext-return" title="getContext-return">return a new object for the <var title="">contextId</var></a> <code title="canvas-context-2d"><a href="#canvas-context-2d">2d</a></code>, the user agent must return a + new <code><a href="#canvasrenderingcontext2d">CanvasRenderingContext2D</a></code> object. Any additional + arguments are ignored.</p> + + </div> + + <p>The 2D context represents a flat Cartesian surface whose origin + (0,0) is at the top left corner, with the coordinate space having + <var title="">x</var> values increasing when going right, and <var title="">y</var> values increasing when going down.</p> + + <pre class="idl">interface <dfn id="canvasrenderingcontext2d">CanvasRenderingContext2D</dfn> { + + // back-reference to the canvas + readonly attribute <a href="#htmlcanvaselement">HTMLCanvasElement</a> <a href="#dom-context-2d-canvas" title="dom-context-2d-canvas">canvas</a>; + + // state + void <a href="#dom-context-2d-save" title="dom-context-2d-save">save</a>(); // push state on state stack + void <a href="#dom-context-2d-restore" title="dom-context-2d-restore">restore</a>(); // pop state stack and restore state +<!-- + // v6 we've also received requests for: + attribute boolean <span title="dom-context-2d-forceHighQuality">forceHighQuality</span> // (default false) + // when enabled, it would prevent the UA from falling back on lower-quality but faster rendering routines + // useful e.g. for when an image manipulation app uses <canvas> both for UI previews and the actual work +--> + // transformations (default transform is the identity matrix) + void <a href="#dom-context-2d-scale" title="dom-context-2d-scale">scale</a>(in double x, in double y); + void <a href="#dom-context-2d-rotate" title="dom-context-2d-rotate">rotate</a>(in double angle); + void <a href="#dom-context-2d-translate" title="dom-context-2d-translate">translate</a>(in double x, in double y); + void <a href="#dom-context-2d-transform" title="dom-context-2d-transform">transform</a>(in double a, in double b, in double c, in double d, in double e, in double f); + void <a href="#dom-context-2d-settransform" title="dom-context-2d-setTransform">setTransform</a>(in double a, in double b, in double c, in double d, in double e, in double f); +<!-- + // v6 we've also received requests for: + void skew(...); + void reflect(...); // or mirror(...) +--> + // compositing + attribute double <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">globalAlpha</a>; // (default 1.0) + attribute DOMString <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">globalCompositeOperation</a>; // (default source-over) +<!-- + // v6 we've also received requests for: + - turning off antialiasing to avoid seams when patterns are painted next to each other + - might be better to overdraw? + - might be better to just draw at a higher res then downsample, like for 3d? + - nested layers + - the ability to composite an entire set of drawing operations with one shadow all at once + http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/015567.html +--> + // colors and styles + attribute any <a href="#dom-context-2d-strokestyle" title="dom-context-2d-strokeStyle">strokeStyle</a>; // (default black) + attribute any <a href="#dom-context-2d-fillstyle" title="dom-context-2d-fillStyle">fillStyle</a>; // (default black) + <a href="#canvasgradient">CanvasGradient</a> <a href="#dom-context-2d-createlineargradient" title="dom-context-2d-createLinearGradient">createLinearGradient</a>(in double x0, in double y0, in double x1, in double y1); + <a href="#canvasgradient">CanvasGradient</a> <a href="#dom-context-2d-createradialgradient" title="dom-context-2d-createRadialGradient">createRadialGradient</a>(in double x0, in double y0, in double r0, in double x1, in double y1, in double r1); + <a href="#canvaspattern">CanvasPattern</a> <a href="#dom-context-2d-createpattern" title="dom-context-2d-createPattern">createPattern</a>(in <a href="#htmlimageelement">HTMLImageElement</a> image, in DOMString repetition); + <a href="#canvaspattern">CanvasPattern</a> <a href="#dom-context-2d-createpattern" title="dom-context-2d-createPattern">createPattern</a>(in <a href="#htmlcanvaselement">HTMLCanvasElement</a> image, in DOMString repetition); + <a href="#canvaspattern">CanvasPattern</a> <a href="#dom-context-2d-createpattern" title="dom-context-2d-createPattern">createPattern</a>(in <a href="#htmlvideoelement">HTMLVideoElement</a> image, in DOMString repetition); + + // line caps/joins + attribute double <a href="#dom-context-2d-linewidth" title="dom-context-2d-lineWidth">lineWidth</a>; // (default 1) + attribute DOMString <a href="#dom-context-2d-linecap" title="dom-context-2d-lineCap">lineCap</a>; // "butt", "round", "square" (default "butt") + attribute DOMString <a href="#dom-context-2d-linejoin" title="dom-context-2d-lineJoin">lineJoin</a>; // "round", "bevel", "miter" (default "miter") + attribute double <a href="#dom-context-2d-miterlimit" title="dom-context-2d-miterLimit">miterLimit</a>; // (default 10) + + // shadows + attribute double <a href="#dom-context-2d-shadowoffsetx" title="dom-context-2d-shadowOffsetX">shadowOffsetX</a>; // (default 0) + attribute double <a href="#dom-context-2d-shadowoffsety" title="dom-context-2d-shadowOffsetY">shadowOffsetY</a>; // (default 0) + attribute double <a href="#dom-context-2d-shadowblur" title="dom-context-2d-shadowBlur">shadowBlur</a>; // (default 0) + attribute DOMString <a href="#dom-context-2d-shadowcolor" title="dom-context-2d-shadowColor">shadowColor</a>; // (default transparent black) + + // rects + void <a href="#dom-context-2d-clearrect" title="dom-context-2d-clearRect">clearRect</a>(in double x, in double y, in double w, in double h); + void <a href="#dom-context-2d-fillrect" title="dom-context-2d-fillRect">fillRect</a>(in double x, in double y, in double w, in double h); + void <a href="#dom-context-2d-strokerect" title="dom-context-2d-strokeRect">strokeRect</a>(in double x, in double y, in double w, in double h); + + // path API + void <a href="#dom-context-2d-beginpath" title="dom-context-2d-beginPath">beginPath</a>(); + void <a href="#dom-context-2d-closepath" title="dom-context-2d-closePath">closePath</a>(); + void <a href="#dom-context-2d-moveto" title="dom-context-2d-moveTo">moveTo</a>(in double x, in double y); + void <a href="#dom-context-2d-lineto" title="dom-context-2d-lineTo">lineTo</a>(in double x, in double y); + void <a href="#dom-context-2d-quadraticcurveto" title="dom-context-2d-quadraticCurveTo">quadraticCurveTo</a>(in double cpx, in double cpy, in double x, in double y); + void <a href="#dom-context-2d-beziercurveto" title="dom-context-2d-bezierCurveTo">bezierCurveTo</a>(in double cp1x, in double cp1y, in double cp2x, in double cp2y, in double x, in double y); + void <a href="#dom-context-2d-arcto" title="dom-context-2d-arcTo">arcTo</a>(in double x1, in double y1, in double x2, in double y2, in double radius); + void <a href="#dom-context-2d-rect" title="dom-context-2d-rect">rect</a>(in double x, in double y, in double w, in double h); + void <a href="#dom-context-2d-arc" title="dom-context-2d-arc">arc</a>(in double x, in double y, in double radius, in double startAngle, in double endAngle, in optional boolean anticlockwise); + void <a href="#dom-context-2d-fill" title="dom-context-2d-fill">fill</a>(); + void <a href="#dom-context-2d-stroke" title="dom-context-2d-stroke">stroke</a>(); + void <a href="#dom-context-2d-drawsystemfocusring" title="dom-context-2d-drawSystemFocusRing">drawSystemFocusRing</a>(in <a href="#element">Element</a> element); + boolean <a href="#dom-context-2d-drawcustomfocusring" title="dom-context-2d-drawCustomFocusRing">drawCustomFocusRing</a>(in <a href="#element">Element</a> element); + void <a href="#dom-context-2d-scrollpathintoview" title="dom-context-2d-scrollPathIntoView">scrollPathIntoView</a>(); + void <a href="#dom-context-2d-clip" title="dom-context-2d-clip">clip</a>(); + boolean <a href="#dom-context-2d-ispointinpath" title="dom-context-2d-isPointInPath">isPointInPath</a>(in double x, in double y); + + // text + attribute DOMString <a href="#dom-context-2d-font" title="dom-context-2d-font">font</a>; // (default 10px sans-serif) + attribute DOMString <a href="#dom-context-2d-textalign" title="dom-context-2d-textAlign">textAlign</a>; // "start", "end", "left", "right", "center" (default: "start") + attribute DOMString <a href="#dom-context-2d-textbaseline" title="dom-context-2d-textBaseline">textBaseline</a>; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic") + void <a href="#dom-context-2d-filltext" title="dom-context-2d-fillText">fillText</a>(in DOMString text, in double x, in double y, in optional double maxWidth); + void <a href="#dom-context-2d-stroketext" title="dom-context-2d-strokeText">strokeText</a>(in DOMString text, in double x, in double y, in optional double maxWidth);<!-- v6DVT + void <span title="dom-context-2d-fillVerticalText">fillVerticalText</span>(in DOMString text, in double x, in double y, in optional double maxHeight); + void <span title="dom-context-2d-strokeVerticalText">strokeVerticalText</span>(in DOMString text, in double x, in double y, in optional double maxHeight); --> + <a href="#textmetrics">TextMetrics</a> <a href="#dom-context-2d-measuretext" title="dom-context-2d-measureText">measureText</a>(in DOMString text); + + // drawing images + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlimageelement">HTMLImageElement</a> image, in double dx, in double dy); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlimageelement">HTMLImageElement</a> image, in double dx, in double dy, in double dw, in double dh); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlimageelement">HTMLImageElement</a> image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlcanvaselement">HTMLCanvasElement</a> image, in double dx, in double dy); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlcanvaselement">HTMLCanvasElement</a> image, in double dx, in double dy, in double dw, in double dh); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlcanvaselement">HTMLCanvasElement</a> image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlvideoelement">HTMLVideoElement</a> image, in double dx, in double dy); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlvideoelement">HTMLVideoElement</a> image, in double dx, in double dy, in double dw, in double dh); + void <a href="#dom-context-2d-drawimage" title="dom-context-2d-drawImage">drawImage</a>(in <a href="#htmlvideoelement">HTMLVideoElement</a> image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh); + + // pixel manipulation + <a href="#imagedata">ImageData</a> <a href="#dom-context-2d-createimagedata" title="dom-context-2d-createImageData">createImageData</a>(in double sw, in double sh); + <a href="#imagedata">ImageData</a> <a href="#dom-context-2d-createimagedata" title="dom-context-2d-createImageData">createImageData</a>(in <a href="#imagedata">ImageData</a> imagedata); + <a href="#imagedata">ImageData</a> <a href="#dom-context-2d-getimagedata" title="dom-context-2d-getImageData">getImageData</a>(in double sx, in double sy, in double sw, in double sh); + void <a href="#dom-context-2d-putimagedata" title="dom-context-2d-putImageData">putImageData</a>(in <a href="#imagedata">ImageData</a> imagedata, in double dx, in double dy); + void <a href="#dom-context-2d-putimagedata" title="dom-context-2d-putImageData">putImageData</a>(in <a href="#imagedata">ImageData</a> imagedata, in double dx, in double dy, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight); +}; + +interface <dfn id="canvasgradient">CanvasGradient</dfn> { + // opaque object + void <a href="#dom-canvasgradient-addcolorstop" title="dom-canvasgradient-addColorStop">addColorStop</a>(in double offset, in DOMString color); +}; + +interface <dfn id="canvaspattern">CanvasPattern</dfn> { + // opaque object +}; + +interface <dfn id="textmetrics">TextMetrics</dfn> { + readonly attribute double <a href="#dom-textmetrics-width" title="dom-textmetrics-width">width</a>; +}; + +interface <dfn id="imagedata">ImageData</dfn> { + readonly attribute unsigned long <a href="#dom-imagedata-width" title="dom-imagedata-width">width</a>; + readonly attribute unsigned long <a href="#dom-imagedata-height" title="dom-imagedata-height">height</a>; + readonly attribute <a href="#canvaspixelarray">CanvasPixelArray</a> <a href="#dom-imagedata-data" title="dom-imagedata-data">data</a>; +}; + +interface <dfn id="canvaspixelarray">CanvasPixelArray</dfn> { + readonly attribute unsigned long <a href="#dom-canvaspixelarray-length" title="dom-canvaspixelarray-length">length</a>; + <a href="#dom-canvaspixelarray-get" title="dom-CanvasPixelArray-get">getter</a> octet (in unsigned long index); + <a href="#dom-canvaspixelarray-set" title="dom-CanvasPixelArray-set">setter</a> void (in unsigned long index, [Clamp] in octet value); +};</pre> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-canvas"><a href="#dom-context-2d-canvas">canvas</a></code></dt> + + <dd> + + <p>Returns the <code><a href="#the-canvas-element">canvas</a></code> element.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-canvas" title="dom-context-2d-canvas"><code>canvas</code></dfn> + attribute must return the <code><a href="#the-canvas-element">canvas</a></code> element that the + context paints on.</p> + + <p>Except where otherwise specified, for the 2D context interface, + any method call with a numeric argument whose value is infinite or a + NaN value must be ignored.</p> + + <!-- + Philip Taylor wrote: + > My experience with some 3d canvas code is that infinities come up in + > naturally harmless places, e.g. having a function that scales by x then + > translates by 1/x and wanting it to work when x=0 (which ought to draw + > nothing, since anything it draws is zero pixels wide), and it's a bit + > annoying to track down and fix those issues, so I'd probably like it if + > they were harmless in canvas methods. Opera appears to silently not draw + > anything if the transformation matrix is not finite, but Firefox throws + > exceptions when passing in non-finite arguments. + --> + + <p>Whenever the CSS value <code title="">currentColor</code> is used + as a color in this API, the "computed value of the 'color' property" + for the purposes of determining the computed value of the <code title="">currentColor</code> keyword is the computed value of the + 'color' property on the element in question at the time that the + color is specified (e.g. when the appropriate attribute is set, or + when the method is called; not when the color is rendered or + otherwise used). If the computed value of the 'color' property is + undefined for a particular case (e.g. because the element is not + <a href="#in-a-document">in a <code>Document</code></a>), then the "computed value + of the 'color' property" for the purposes of determining the + computed value of the <code title="">currentColor</code> keyword is + fully opaque black. <a href="#refsCSSCOLOR">[CSSCOLOR]</a></p> + + <p>In the case of <code title="dom-canvasgradient-addColorStop"><a href="#dom-canvasgradient-addcolorstop">addColorStop()</a></code> on + <code><a href="#canvasgradient">CanvasGradient</a></code>, the "computed value of the 'color' + property" for the purposes of determining the computed value of the + <code title="">currentColor</code> keyword is always fully opaque + black (there is no associated element). <a href="#refsCSSCOLOR">[CSSCOLOR]</a></p> + + <p class="note">This is because <code><a href="#canvasgradient">CanvasGradient</a></code> objects + are <code><a href="#the-canvas-element">canvas</a></code>-neutral — a + <code><a href="#canvasgradient">CanvasGradient</a></code> object created by one + <code><a href="#the-canvas-element">canvas</a></code> can be used by another, and there is therefore + no way to know which is the "element in question" at the time that + the color is specified.</p> + + </div> + + + + <h6 id="the-canvas-state"><span class="secno">4.8.11.1.1 </span>The canvas state</h6> + + <p>Each context maintains a stack of drawing states. <dfn id="drawing-state" title="drawing state">Drawing states</dfn> consist of:</p> + + <ul class="brief"><li>The current <a href="#transformations" title="dom-context-2d-transformation">transformation matrix</a>.</li> + <li>The current <a href="#clipping-region">clipping region</a>.</li> + <li>The current values of the following attributes: <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code>, <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code>, <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code>, <code title="dom-context-2d-lineWidth"><a href="#dom-context-2d-linewidth">lineWidth</a></code>, <code title="dom-context-2d-lineCap"><a href="#dom-context-2d-linecap">lineCap</a></code>, <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code>, <code title="dom-context-2d-miterLimit"><a href="#dom-context-2d-miterlimit">miterLimit</a></code>, <code title="dom-context-2d-shadowOffsetX"><a href="#dom-context-2d-shadowoffsetx">shadowOffsetX</a></code>, <code title="dom-context-2d-shadowOffsetY"><a href="#dom-context-2d-shadowoffsety">shadowOffsetY</a></code>, <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code>, <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code>, <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code>, <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code>, <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code>, <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code>.</li> + </ul><p class="note">The current path and the current bitmap are not part + of the drawing state. The current path is persistent, and can only + be reset using the <code title="dom-context-2d-beginPath"><a href="#dom-context-2d-beginpath">beginPath()</a></code> method. The + current bitmap is a property of the canvas, not the context.</p> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-save"><a href="#dom-context-2d-save">save</a></code>()</dt> + + <dd> + + <p>Pushes the current state onto the stack.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-restore"><a href="#dom-context-2d-restore">restore</a></code>()</dt> + + <dd> + + <p>Pops the top state on the stack, restoring the context to that state.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-save" title="dom-context-2d-save"><code>save()</code></dfn> + method must push a copy of the current drawing state onto the + drawing state stack.</p> + + <p>The <dfn id="dom-context-2d-restore" title="dom-context-2d-restore"><code>restore()</code></dfn> method + must pop the top entry in the drawing state stack, and reset the + drawing state it describes. If there is no saved state, the method + must do nothing.</p> + + <!-- v6 +idea from Mihai: +> 5. Drawing states should be saveable with IDs, and for easier restoring. +> +> save(id) +> restore(id) +> +> If id is not provided, then save() works as defined now. The same for +> restore(). +> +> Currently, it's not trivial to save and restore a specific state. +...and from Philip: +> I think a more convenient syntax would be: +> var state = ctx.save(); +> ctx.restore(state); +> But how would it interact with normal calls to ctx.restore()? + --> + + </div> + + + <h6 id="transformations"><span class="secno">4.8.11.1.2 </span><dfn title="dom-context-2d-transformation">Transformations</dfn></h6> + + <p>The transformation matrix is applied to coordinates when creating + shapes and paths.</p> <!-- conformance criteria for actual drawing + are described in the various sections below --> + + <div class="impl"> + + <p>When the context is created, the transformation matrix must + initially be the identity transform. It may then be adjusted using + the transformation methods.</p> + + <p>The transformations must be performed in reverse order. For + instance, if a scale transformation that doubles the width is + applied, followed by a rotation transformation that rotates drawing + operations by a quarter turn, and a rectangle twice as wide as it is + tall is then drawn on the canvas, the actual result will be a + square.</p> + + </div> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-scale"><a href="#dom-context-2d-scale">scale</a></code>(<var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Changes the transformation matrix to apply a scaling transformation with the given characteristics.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-rotate"><a href="#dom-context-2d-rotate">rotate</a></code>(<var title="">angle</var>)</dt> + + <dd> + + <p>Changes the transformation matrix to apply a rotation transformation with the given characteristics. The angle is in radians.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-translate"><a href="#dom-context-2d-translate">translate</a></code>(<var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Changes the transformation matrix to apply a translation transformation with the given characteristics.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-transform"><a href="#dom-context-2d-transform">transform</a></code>(<var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, <var title="">f</var>)</dt> + + <dd> + + <p>Changes the transformation matrix to apply the matrix given by the arguments as described below.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-setTransform"><a href="#dom-context-2d-settransform">setTransform</a></code>(<var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, <var title="">f</var>)</dt> + + <dd> + + <p>Changes the transformation matrix <em>to</em> the matrix given by the arguments as described below.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-scale" title="dom-context-2d-scale"><code>scale(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must + add the scaling transformation described by the arguments to the + transformation matrix. The <var title="">x</var> argument represents + the scale factor in the horizontal direction and the <var title="">y</var> argument represents the scale factor in the + vertical direction. The factors are multiples.</p> + + <p>The <dfn id="dom-context-2d-rotate" title="dom-context-2d-rotate"><code>rotate(<var title="">angle</var>)</code></dfn> method must add the rotation + transformation described by the argument to the transformation + matrix. The <var title="">angle</var> argument represents a + clockwise rotation angle expressed in radians.</p> + + <p>The <dfn id="dom-context-2d-translate" title="dom-context-2d-translate"><code>translate(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must + add the translation transformation described by the arguments to the + transformation matrix. The <var title="">x</var> argument represents + the translation distance in the horizontal direction and the <var title="">y</var> argument represents the translation distance in the + vertical direction. The arguments are in coordinate space units.</p> + + <p>The <dfn id="dom-context-2d-transform" title="dom-context-2d-transform"><code>transform(<var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, <var title="">f</var>)</code></dfn> method must replace the current + transformation matrix with the result of multiplying the current + transformation matrix with the matrix described by:</p> + + </div> + + <table class="matrix"><tbody><tr><td><var title="">a</var></td> + <td><var title="">c</var></td> + <td><var title="">e</var></td> + </tr><tr><td><var title="">b</var></td> + <td><var title="">d</var></td> + <td><var title="">f</var></td> + </tr><tr><td>0</td> + <td>0</td> + <td>1</td> + </tr></tbody></table><p class="note">The arguments <var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, and <var title="">f</var> are sometimes called + <var title="">m11</var>, <var title="">m12</var>, <var title="">m21</var>, <var title="">m22</var>, <var title="">dx</var>, + and <var title="">dy</var> or <var title="">m11</var>, <var title="">m21</var>, <var title="">m12</var>, <var title="">m22</var>, <var title="">dx</var>, and <var title="">dy</var>. Care should be taken in particular with the order + of the second and third arguments (<var title="">b</var> and <var title="">c</var>) as their order varies from API to API and APIs + sometimes use the notation <var title="">m12</var>/<var title="">m21</var> and sometimes <var title="">m21</var>/<var title="">m12</var> for those positions.</p> + + <div class="impl"> + + <p>The <dfn id="dom-context-2d-settransform" title="dom-context-2d-setTransform"><code>setTransform(<var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, + <var title="">f</var>)</code></dfn> method must reset the current + transform to the identity matrix, and then invoke the <code><a href="#dom-context-2d-transform" title="dom-context-2d-transform">transform</a>(<var title="">a</var>, <var title="">b</var>, <var title="">c</var>, <var title="">d</var>, <var title="">e</var>, + <var title="">f</var>)</code> method with the same arguments.</p> + + </div> + + + <h6 id="compositing"><span class="secno">4.8.11.1.3 </span>Compositing</h6> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current alpha value applied to rendering operations.</p> + + <p>Can be set, to change the alpha value. Values outside of the + range 0.0 .. 1.0 are ignored.</p> + + </dd> + + + <dt><var title="">context</var> . <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current composition operation, from the list below.</p> + + <p>Can be set, to change the composition operation. Unknown values + are ignored.</p> + + </dd> + + </dl><div class="impl"> + + <p>All drawing operations are affected by the global compositing + attributes, <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code> and <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code>.</p> + + <!-- conformance criteria for painting are described in the "drawing + model" section below --> + + <p>The <dfn id="dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha"><code>globalAlpha</code></dfn> + attribute gives an alpha value that is applied to shapes and images + before they are composited onto the canvas. The value must be in the + range from 0.0 (fully transparent) to 1.0 (no additional + transparency). If an attempt is made to set the attribute to a value + outside this range, including Infinity and Not-a-Number (NaN) + values, the attribute must retain its previous value. When the + context is created, the <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code> attribute must + initially have the value 1.0.</p> + + <p>The <dfn id="dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation"><code>globalCompositeOperation</code></dfn> + attribute sets how shapes and images are drawn onto the existing + bitmap, once they have had <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code> and the + current transformation matrix applied. It must be set to a value + from the following list. In the descriptions below, the source + image, <var title="">A</var>, is the shape or image being rendered, + and the destination image, <var title="">B</var>, is the current + state of the bitmap.</p> + + </div> + + <dl><dt><dfn id="gcop-source-atop" title="gcop-source-atop"><code>source-atop</code></dfn></dt> + + <dd><var title="">A</var> atop <var title="">B</var>. <span class="note">Display the + source image wherever both images are opaque. Display the + destination image wherever the destination image is opaque but the + source image is transparent. Display transparency elsewhere.</span></dd> + + <dt><dfn id="gcop-source-in" title="gcop-source-in"><code>source-in</code></dfn></dt> + + <dd><var title="">A</var> in <var title="">B</var>. <span class="note">Display the + source image wherever both the source image and destination image + are opaque. Display transparency elsewhere.</span></dd> + + <dt><dfn id="gcop-source-out" title="gcop-source-out"><code>source-out</code></dfn></dt> + + <dd><var title="">A</var> out <var title="">B</var>. <span class="note">Display the + source image wherever the source image is opaque and the + destination image is transparent. Display transparency + elsewhere.</span></dd> + + <dt><dfn id="gcop-source-over" title="gcop-source-over"><code>source-over</code></dfn> (default)</dt> + + <dd><var title="">A</var> over <var title="">B</var>. <span class="note">Display the + source image wherever the source image is opaque. Display the + destination image elsewhere.</span></dd> + + + <dt><dfn id="gcop-destination-atop" title="gcop-destination-atop"><code>destination-atop</code></dfn></dt> + + <dd><var title="">B</var> atop <var title="">A</var>. <span class="note">Same as <code title="gcop-source-atop"><a href="#gcop-source-atop">source-atop</a></code> but using the + destination image instead of the source image and vice versa.</span></dd> + + <dt><dfn id="gcop-destination-in" title="gcop-destination-in"><code>destination-in</code></dfn></dt> + + <dd><var title="">B</var> in <var title="">A</var>. <span class="note">Same as <code title="gcop-source-in"><a href="#gcop-source-in">source-in</a></code> but using the destination + image instead of the source image and vice versa.</span></dd> + + <dt><dfn id="gcop-destination-out" title="gcop-destination-out"><code>destination-out</code></dfn></dt> + + <dd><var title="">B</var> out <var title="">A</var>. <span class="note">Same as <code title="gcop-source-out"><a href="#gcop-source-out">source-out</a></code> but using the destination + image instead of the source image and vice versa.</span></dd> + + <dt><dfn id="gcop-destination-over" title="gcop-destination-over"><code>destination-over</code></dfn></dt> + + <dd><var title="">B</var> over <var title="">A</var>. <span class="note">Same as <code title="gcop-source-over"><a href="#gcop-source-over">source-over</a></code> but using the + destination image instead of the source image and vice versa.</span></dd> + + +<!-- no clear definition of this operator (doesn't correspond to a PorterDuff operator) + <dt><dfn title="gcop-darker"><code>darker</code></dfn></dt> + + <dd><span class="note">Display the sum of the source image and destination image, + with color values approaching 0 as a limit.</span></dd> +--> + + <dt><dfn id="gcop-lighter" title="gcop-lighter"><code>lighter</code></dfn></dt> + + <dd><var title="">A</var> plus <var title="">B</var>. <span class="note">Display the + sum of the source image and destination image, with color values + approaching 255 (100%) as a limit.</span></dd> + + + <dt><dfn id="gcop-copy" title="gcop-copy"><code>copy</code></dfn></dt> + + <dd><var title="">A</var> (<var title="">B</var> is + ignored). <span class="note">Display the source image instead of the destination + image.</span></dd> + + + <dt><dfn id="gcop-xor" title="gcop-xor"><code>xor</code></dfn></dt> + + <dd><var title="">A</var> xor <var title="">B</var>. <span class="note">Exclusive OR + of the source image and destination image.</span></dd> + + + <dt class="impl"><code><var title="">vendorName</var>-<var title="">operationName</var></code></dt> + + <dd class="impl">Vendor-specific extensions to the list of + composition operators should use this syntax.</dd> + + </dl><div class="impl"> + + <p>The operators in the above list must be treated as described by + the Porter-Duff operator given at the start of their description + (e.g. <var title="">A</var> over <var title="">B</var>). They are to + be applied as part of the <a href="#drawing-model">drawing model</a>, at which point the + <a href="#clipping-region">clipping region</a> is also applied. (Without a clipping + region, these operators act on the whole bitmap with every + operation.) <a href="#refsPORTERDUFF">[PORTERDUFF]</a></p> + + <p>These values are all case-sensitive — they must be used + exactly as shown. User agents must not recognize values that are not + a <a href="#case-sensitive">case-sensitive</a> match for one of the values given + above.</p> + + <p>On setting, if the user agent does not recognize the specified + value, it must be ignored, leaving the value of <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code> + unaffected.</p> + + <p>When the context is created, the <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code> + attribute must initially have the value + <code>source-over</code>.</p> + + </div> + + + <h6 id="colors-and-styles"><span class="secno">4.8.11.1.4 </span>Colors and styles</h6> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current style used for stroking shapes.</p> + + <p>Can be set, to change the stroke style.</p> + + <p>The style can be either a string containing a CSS color, or a + <code><a href="#canvasgradient">CanvasGradient</a></code> or <code><a href="#canvaspattern">CanvasPattern</a></code> + object. Invalid values are ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current style used for filling shapes.</p> + + <p>Can be set, to change the fill style.</p> + + <p>The style can be either a string containing a CSS color, or a + <code><a href="#canvasgradient">CanvasGradient</a></code> or <code><a href="#canvaspattern">CanvasPattern</a></code> + object. Invalid values are ignored.</p> + + </dd> + + </dl><div class="impl"> + + <!-- v6 feature requests: + + * Getting and setting colours by component to bypass the CSS value parsing. + + Either: + context.fillStyle.red += 1; + + Or: + var array = context.fillStyle; + array[1] += 1; + context.fillStyle = array; + + * A more performant way of setting colours in general, e.g.: + + context.setFillColor(r,g,b,a) // already supported by webkit + + Or: + + context.fillStyle = 0xRRGGBBAA; // set a 32bit int directly + + * fill rule for deciding between winding and even-odd algorithms. + SVG has fill-rule: nonzero | evenodd + http://www.w3.org/TR/SVG/painting.html#FillProperties + + --> + + <p>The <dfn id="dom-context-2d-strokestyle" title="dom-context-2d-strokeStyle"><code>strokeStyle</code></dfn> + attribute represents the color or style to use for the lines around + shapes, and the <dfn id="dom-context-2d-fillstyle" title="dom-context-2d-fillStyle"><code>fillStyle</code></dfn> + attribute represents the color or style to use inside the + shapes.</p> + + <p>Both attributes can be either strings, + <code><a href="#canvasgradient">CanvasGradient</a></code>s, or <code><a href="#canvaspattern">CanvasPattern</a></code>s. On + setting, strings must be <a href="#parsed-as-a-css-color-value" title="parsed as a CSS <color> + value">parsed as CSS <color> values</a> and the color + assigned, and <code><a href="#canvasgradient">CanvasGradient</a></code> and + <code><a href="#canvaspattern">CanvasPattern</a></code> objects must be assigned themselves. <a href="#refsCSSCOLOR">[CSSCOLOR]</a> If the value is a string but + cannot be <a href="#parsed-as-a-css-color-value">parsed as a CSS <color> value</a>, or is + neither a string, a <code><a href="#canvasgradient">CanvasGradient</a></code>, nor a + <code><a href="#canvaspattern">CanvasPattern</a></code>, then it must be ignored, and the + attribute must retain its previous value.</p> + + <p>When set to a <code><a href="#canvaspattern">CanvasPattern</a></code> or + <code><a href="#canvasgradient">CanvasGradient</a></code> object, the assignment is + <a href="#live">live</a>, meaning that changes made to the object after the + assignment do affect subsequent stroking or filling of shapes.</p> + + <p>On getting, if the value is a color, then the <a href="#serialization-of-a-color" title="serialization of a color">serialization of the color</a> + must be returned. Otherwise, if it is not a color but a + <code><a href="#canvasgradient">CanvasGradient</a></code> or <code><a href="#canvaspattern">CanvasPattern</a></code>, then the + respective object must be returned. (Such objects are opaque and + therefore only useful for assigning to other attributes or for + comparison to other gradients or patterns.)</p> + + <p>The <dfn id="serialization-of-a-color">serialization of a color</dfn> for a color value is a + string, computed as follows: if it has alpha equal to 1.0, then the + string is a lowercase six-digit hex value, prefixed with a "#" + character (U+0023 NUMBER SIGN), with the first two digits + representing the red component, the next two digits representing the + green component, and the last two digits representing the blue + component, the digits being in the range 0-9 a-f (U+0030 to U+0039 + and U+0061 to U+0066). Otherwise, the color value has alpha less + than 1.0, and the string is the color value in the CSS <code title="">rgba()</code> functional-notation format: the literal + string <code title="">rgba</code> (U+0072 U+0067 U+0062 U+0061) + followed by a U+0028 LEFT PARENTHESIS, a base-ten integer in the + range 0-255 representing the red component (using digits 0-9, U+0030 + to U+0039, in the shortest form possible), a literal U+002C COMMA + and U+0020 SPACE, an integer for the green component, a comma and a + space, an integer for the blue component, another comma and space, a + U+0030 DIGIT ZERO, if the alpha value is greater than zero then a + U+002E FULL STOP (representing the decimal point), if the alpha + value is greater than zero then one or more digits in the range 0-9 + (U+0030 to U+0039) representing the fractional part of the alpha + value, and finally a U+0029 RIGHT PARENTHESIS.</p> <!-- if people + complain this is unreadable, expand it into a <dl> with two nested + <ol>s --> + + <p>When the context is created, the <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> and <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> attributes must + initially have the string value <code title="">#000000</code>.</p> + + </div> + + <hr/><p>There are two types of gradients, linear gradients and radial + gradients, both represented by objects implementing the opaque + <code><a href="#canvasgradient">CanvasGradient</a></code> interface.</p> + + <p id="interpolation">Once a gradient has been created (see below), + stops are placed along it to define how the colors are distributed + along the gradient. <span class="impl">The color of the gradient at + each stop is the color specified for that stop. Between each such + stop, the colors and the alpha component must be linearly + interpolated over the RGBA space without premultiplying the alpha + value to find the color to use at that offset. Before the first + stop, the color must be the color of the first stop. After the last + stop, the color must be the color of the last stop. When there are + no stops, the gradient is transparent black.</span></p> + + <dl class="domintro"><dt><var title="">gradient</var> . <code title="dom-canvasgradient-addColorStop"><a href="#dom-canvasgradient-addcolorstop">addColorStop</a></code>(<var title="">offset</var>, <var title="">color</var>)</dt> + + <dd> + + <p>Adds a color stop with the given color to the gradient at the + given offset. 0.0 is the offset at one end of the gradient, 1.0 is + the offset at the other end.</p> + + <p>Throws an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception if the offset + is out of range. Throws a <code><a href="#syntax_err">SYNTAX_ERR</a></code> exception if the + color cannot be parsed.</p> + + </dd> + + <dt><var title="">gradient</var> = <var title="">context</var> . <code title="dom-context-2d-createLinearGradient"><a href="#dom-context-2d-createlineargradient">createLinearGradient</a></code>(<var title="">x0</var>, <var title="">y0</var>, <var title="">x1</var>, <var title="">y1</var>)</dt> + + <dd> + + <p>Returns a <code><a href="#canvasgradient">CanvasGradient</a></code> object that represents a + linear gradient that paints along the line given by the + coordinates represented by the arguments.</p> + + <p>If any of the arguments are not finite numbers, throws a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception.</p> + + </dd> + + <dt><var title="">gradient</var> = <var title="">context</var> . <code title="dom-context-2d-createRadialGradient"><a href="#dom-context-2d-createradialgradient">createRadialGradient</a></code>(<var title="">x0</var>, <var title="">y0</var>, <var title="">r0</var>, <var title="">x1</var>, <var title="">y1</var>, <var title="">r1</var>)</dt> + + <dd> + + <p>Returns a <code><a href="#canvasgradient">CanvasGradient</a></code> object that represents a + radial gradient that paints along the cone given by the circles + represented by the arguments.</p> + + <p>If any of the arguments are not finite numbers, throws a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception. If either of the radii + are negative, throws an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-canvasgradient-addcolorstop" title="dom-canvasgradient-addColorStop"><code>addColorStop(<var title="">offset</var>, <var title="">color</var>)</code></dfn> + method on the <code><a href="#canvasgradient">CanvasGradient</a></code> interface adds a new stop + to a gradient. If the <var title="">offset</var> is less than 0, + greater than 1, infinite, or NaN, then an + <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception must be raised. If the <var title="">color</var> cannot be <a href="#parsed-as-a-css-color-value">parsed as a CSS <color> + value</a>, then a <code><a href="#syntax_err">SYNTAX_ERR</a></code> exception must be + raised. Otherwise, the gradient must have a new stop placed, at + offset <var title="">offset</var> relative to the whole gradient, + and with the color obtained by parsing <var title="">color</var> as + a CSS <color> value. If multiple stops are added at the same + offset on a gradient, they must be placed in the order added, with + the first one closest to the start of the gradient, and each + subsequent one infinitesimally further along towards the end point + (in effect causing all but the first and last stop added at each + point to be ignored).</p> + + <p>The <dfn id="dom-context-2d-createlineargradient" title="dom-context-2d-createLinearGradient"><code>createLinearGradient(<var title="">x0</var>, <var title="">y0</var>, <var title="">x1</var>, + <var title="">y1</var>)</code></dfn> method takes four arguments + that represent the start point (<var title="">x0</var>, <var title="">y0</var>) and end point (<var title="">x1</var>, <var title="">y1</var>) of the gradient. If any of the arguments to <code title="dom-context-2d-createLinearGradient"><a href="#dom-context-2d-createlineargradient">createLinearGradient()</a></code> + are infinite or NaN, the method must raise a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception. Otherwise, the method must + return a linear <code><a href="#canvasgradient">CanvasGradient</a></code> initialized with the + specified line.</p> + + <p>Linear gradients must be rendered such that all points on a line + perpendicular to the line that crosses the start and end points have + the color at the point where those two lines cross (with the colors + coming from the <a href="#interpolation">interpolation and + extrapolation</a> described above). The points in the linear + gradient must be transformed as described by the <a href="#transformations" title="dom-context-2d-transformation">current transformation + matrix</a> when rendering.</p> + + <p>If <span title=""><var title="">x0</var> = <var title="">x1</var></span> and <span title=""><var title="">y0</var> = <var title="">y1</var></span>, then + the linear gradient must paint nothing.</p> + + <p>The <dfn id="dom-context-2d-createradialgradient" title="dom-context-2d-createRadialGradient"><code>createRadialGradient(<var title="">x0</var>, <var title="">y0</var>, <var title="">r0</var>, + <var title="">x1</var>, <var title="">y1</var>, <var title="">r1</var>)</code></dfn> method takes six arguments, the + first three representing the start circle with origin (<var title="">x0</var>, <var title="">y0</var>) and radius <var title="">r0</var>, and the last three representing the end circle + with origin (<var title="">x1</var>, <var title="">y1</var>) and + radius <var title="">r1</var>. The values are in coordinate space + units. If any of the arguments are infinite or NaN, a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception must be raised. If either + of <var title="">r0</var> or <var title="">r1</var> are negative, an + <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception must be raised. Otherwise, + the method must return a radial <code><a href="#canvasgradient">CanvasGradient</a></code> + initialized with the two specified circles.</p> + + <p>Radial gradients must be rendered by following these steps:</p> + + <ol><li><p>If <span title=""><var title="">x<sub>0</sub></var> = <var title="">x<sub>1</sub></var></span> and <span title=""><var title="">y<sub>0</sub></var> = <var title="">y<sub>1</sub></var></span> and <span title=""><var title="">r<sub>0</sub></var> = <var title="">r<sub>1</sub></var></span>, then the radial gradient must + paint nothing. Abort these steps.</p></li> + + <li> + + <p>Let <span title="">x(<var title="">ω</var>) = (<var title="">x<sub>1</sub></var>-<var title="">x<sub>0</sub></var>)<var title="">ω</var> + <var title="">x<sub>0</sub></var></span></p> + + <p>Let <span title="">y(<var title="">ω</var>) = (<var title="">y<sub>1</sub></var>-<var title="">y<sub>0</sub></var>)<var title="">ω</var> + <var title="">y<sub>0</sub></var></span></p> + + <p>Let <span title="">r(<var title="">ω</var>) = (<var title="">r<sub>1</sub></var>-<var title="">r<sub>0</sub></var>)<var title="">ω</var> + <var title="">r<sub>0</sub></var></span></p> + + <p>Let the color at <var title="">ω</var> be the color at + that position on the gradient (with the colors coming from the <a href="#interpolation">interpolation and extrapolation</a> + described above).</p> + + </li> + + <li><p>For all values of <var title="">ω</var> where <span title="">r(<var title="">ω</var>) > 0</span>, + starting with the value of <var title="">ω</var> nearest to + positive infinity and ending with the value of <var title="">ω</var> nearest to negative infinity, draw the + circumference of the circle with radius <span title="">r(<var title="">ω</var>)</span> at position (<span title="">x(<var title="">ω</var>)</span>, <span title="">y(<var title="">ω</var>)</span>), with the color at <var title="">ω</var>, but only painting on the parts of the + canvas that have not yet been painted on by earlier circles in this + step for this rendering of the gradient.</p></li> + + </ol><p class="note">This effectively creates a cone, touched by the two + circles defined in the creation of the gradient, with the part of + the cone before the start circle (0.0) using the color of the first + offset, the part of the cone after the end circle (1.0) using the + color of the last offset, and areas outside the cone untouched by + the gradient (transparent black).</p> + + <p>The points in the radial gradient must be transformed as + described by the <a href="#transformations" title="dom-context-2d-transformation">current + transformation matrix</a> when rendering.</p> + + <p>Gradients must be painted only where the relevant stroking or + filling effects requires that they be drawn.</p> + +<!-- + <p>Support for actually painting gradients is optional. Instead of + painting the gradients, user agents may instead just paint the first + stop's color. However, <code + title="dom-context-2d-createLinearGradient">createLinearGradient()</code> + and <code + title="dom-context-2d-createRadialGradient">createRadialGradient()</code> + must always return objects when passed valid arguments.</p> +--> + + </div> + + <hr/><p>Patterns are represented by objects implementing the opaque + <code><a href="#canvaspattern">CanvasPattern</a></code> interface.</p> + + <dl class="domintro"><dt><var title="">pattern</var> = <var title="">context</var> . <code title="dom-context-2d-createPattern"><a href="#dom-context-2d-createpattern">createPattern</a></code>(<var title="">image</var>, <var title="">repetition</var>)</dt> + + <dd> + + <p>Returns a <code><a href="#canvaspattern">CanvasPattern</a></code> object that uses the given image + and repeats in the direction(s) given by the <var title="">repetition</var> argument.</p> + + <p>The allowed values for <var title="">repetition</var> are <code title="">repeat</code> (both directions), <code title="">repeat-x</code> (horizontal only), <code title="">repeat-y</code> (vertical only), and <code title="">no-repeat</code> (neither). If the <var title="">repetition</var> argument is empty, the value <code title="">repeat</code> is used.</p> + + <p>If the image has no image data, throws an + <code><a href="#invalid_state_err">INVALID_STATE_ERR</a></code> exception. If the second argument + isn't one of the allowed values, throws a <code><a href="#syntax_err">SYNTAX_ERR</a></code> + exception. If the image isn't yet fully decoded, then the method + returns null.</p> + + </dd> + + </dl><div class="impl"> + + <p>To create objects of this type, the <dfn id="dom-context-2d-createpattern" title="dom-context-2d-createPattern"><code>createPattern(<var title="">image</var>, <var title="">repetition</var>)</code></dfn> + method is used. The first argument gives the image to use as the + pattern (either an <code><a href="#htmlimageelement">HTMLImageElement</a></code>, + <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, or <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> + object). Modifying this image after calling the <code title="dom-context-2d-createPattern"><a href="#dom-context-2d-createpattern">createPattern()</a></code> method + must not affect the pattern. The second argument must be a string + with one of the following values: <code title="">repeat</code>, + <code title="">repeat-x</code>, <code title="">repeat-y</code>, + <code title="">no-repeat</code>. If the empty string is specified, + <code title="">repeat</code> must be assumed. If an unrecognized value + is given, then the user agent must raise a <code><a href="#syntax_err">SYNTAX_ERR</a></code> + exception. User agents must recognize the four values described above + exactly (e.g. they must not do case folding). Except as specified + below, the method must return a <code><a href="#canvaspattern">CanvasPattern</a></code> object + suitably initialized.</p> + + <p>The <var title="">image</var> argument is an instance of either + <code><a href="#htmlimageelement">HTMLImageElement</a></code>, <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, or + <code><a href="#htmlvideoelement">HTMLVideoElement</a></code>.</p> <!-- drawImage() has an equivalent + paragraph --> + + <p>If the <var title="">image</var> argument is an + <code><a href="#htmlimageelement">HTMLImageElement</a></code> object that is not <a href="#img-good" title="img-good">fully decodable</a>, or if the <var title="">image</var> argument is an <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> + object whose <code title="dom-media-readyState"><a href="#dom-media-readystate">readyState</a></code> + attribute is either <code title="dom-media-HAVE_NOTHING"><a href="#dom-media-have_nothing">HAVE_NOTHING</a></code> or <code title="dom-media-HAVE_METADATA"><a href="#dom-media-have_metadata">HAVE_METADATA</a></code>, then the + implementation must return null.</p> <!-- drawImage() has an + equivalent paragraph --> + + <p>If the <var title="">image</var> argument is an + <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> object with either a horizontal + dimension or a vertical dimension equal to zero, then the + implementation must raise an <code><a href="#invalid_state_err">INVALID_STATE_ERR</a></code> + exception.</p> + <!-- drawImage() has an equivalent paragraph --> + + <p>Patterns must be painted so that the top left of the first image + is anchored at the origin of the coordinate space, and images are + then repeated horizontally to the left and right (if the + <code>repeat-x</code> string was specified) or vertically up and + down (if the <code>repeat-y</code> string was specified) or in all + four directions all over the canvas (if the <code>repeat</code> + string was specified). The images are not scaled by this process; + one CSS pixel of the image must be painted on one coordinate space + unit. Of course, patterns must actually be painted only where the + stroking or filling effect requires that they be drawn, and are + affected by the current transformation matrix.</p> + + <p>If the original image data is a bitmap image, the value painted + at a point in the area of the repetitions is computed by filtering + the original image data. The user agent may use any filtering + algorithm (for example bilinear interpolation or nearest-neighbor). + When the filtering algorithm requires a pixel value from outside the + original image data, it must instead use the value from wrapping the + pixel's coordinates to the original image's dimensions. (That is, + the filter uses 'repeat' behavior, regardless of the value of + <var title="">repetition</var>.) + <!-- drawImage() has a similar paragraph with different rules --> + + </p><p>When the <code title="dom-context-2d-createPattern"><a href="#dom-context-2d-createpattern">createPattern()</a></code> method + is passed an animated image as its <var title="">image</var> + argument, the user agent must use the poster frame of the animation, + or, if there is no poster frame, the first frame of the + animation.</p> + <!-- drawImage() has an equivalent paragraph --> + + <p>When the <var title="">image</var> argument is an + <code><a href="#htmlvideoelement">HTMLVideoElement</a></code>, then the frame at the <a href="#current-playback-position">current + playback position</a> must be used as the source image, and the + source image's dimensions must be the <a href="#concept-video-intrinsic-width" title="concept-video-intrinsic-width">intrinsic width</a> and + <a href="#concept-video-intrinsic-height" title="concept-video-intrinsic-height">intrinsic height</a> + of the <a href="#media-resource">media resource</a> (i.e. after any aspect-ratio + correction has been applied).</p> + <!-- drawImage() has an equivalent paragraph --> + + <!-- + Requests for v6 features: + * apply transforms to patterns, so you don't have to create + transformed patterns manually by rendering them to an off-screen + canvas then using that canvas as the pattern. + --> + + </div> + + + + <h6 id="line-styles"><span class="secno">4.8.11.1.5 </span>Line styles</h6> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-lineWidth"><a href="#dom-context-2d-linewidth">lineWidth</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current line width.</p> + + <p>Can be set, to change the line width. Values that are not + finite values greater than zero are ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-lineCap"><a href="#dom-context-2d-linecap">lineCap</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current line cap style.</p> + + <p>Can be set, to change the line cap style.</p> + + <p>The possible line cap styles are <code>butt</code>, + <code>round</code>, and <code>square</code>. Other values are + ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current line join style.</p> + + <p>Can be set, to change the line join style.</p> + + <p>The possible line join styles are <code>bevel</code>, + <code>round</code>, and <code>miter</code>. Other values are + ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-miterLimit"><a href="#dom-context-2d-miterlimit">miterLimit</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current miter limit ratio.</p> + + <p>Can be set, to change the miter limit ratio. Values that are + not finite values greater than zero are ignored.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-linewidth" title="dom-context-2d-lineWidth"><code>lineWidth</code></dfn> + attribute gives the width of lines, in coordinate space units. On + getting, it must return the current value. On setting, zero, + negative, infinite, and NaN values must be ignored, leaving the + value unchanged; other values must change the current value to the + new value.</p> + + <p>When the context is created, the <code title="dom-context-2d-lineWidth"><a href="#dom-context-2d-linewidth">lineWidth</a></code> attribute must + initially have the value <code>1.0</code>.</p> + + <hr/><p>The <dfn id="dom-context-2d-linecap" title="dom-context-2d-lineCap"><code>lineCap</code></dfn> attribute + defines the type of endings that UAs will place on the end of + lines. The three valid values are <code>butt</code>, + <code>round</code>, and <code>square</code>. The <code>butt</code> + value means that the end of each line has a flat edge perpendicular + to the direction of the line (and that no additional line cap is + added). The <code>round</code> value means that a semi-circle with + the diameter equal to the width of the line must then be added on to + the end of the line. The <code>square</code> value means that a + rectangle with the length of the line width and the width of half + the line width, placed flat against the edge perpendicular to the + direction of the line, must be added at the end of each line.</p> + + <p>On getting, it must return the current value. On setting, if the + new value is one of the literal strings <code>butt</code>, + <code>round</code>, and <code>square</code>, then the current value + must be changed to the new value; other values must ignored, leaving + the value unchanged.</p> + + <p>When the context is created, the <code title="dom-context-2d-lineCap"><a href="#dom-context-2d-linecap">lineCap</a></code> attribute must + initially have the value <code>butt</code>.</p> + + <hr/><p>The <dfn id="dom-context-2d-linejoin" title="dom-context-2d-lineJoin"><code>lineJoin</code></dfn> + attribute defines the type of corners that UAs will place where two + lines meet. The three valid values are <code>bevel</code>, + <code>round</code>, and <code>miter</code>.</p> + + <p>On getting, it must return the current value. On setting, if the + new value is one of the literal strings <code>bevel</code>, + <code>round</code>, and <code>miter</code>, then the current value + must be changed to the new value; other values must be ignored, + leaving the value unchanged.</p> + + <p>When the context is created, the <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code> attribute must + initially have the value <code>miter</code>.</p> + + <hr/><p>A join exists at any point in a subpath shared by two consecutive + lines. When a subpath is closed, then a join also exists at its + first point (equivalent to its last point) connecting the first and + last lines in the subpath.</p> + + <p>In addition to the point where the join occurs, two additional + points are relevant to each join, one for each line: the two corners + found half the line width away from the join point, one + perpendicular to each line, each on the side furthest from the other + line.</p> + + <p>A filled triangle connecting these two opposite corners with a + straight line, with the third point of the triangle being the join + point, must be rendered at all joins. The <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code> attribute controls + whether anything else is rendered. The three aforementioned values + have the following meanings:</p> + + <p>The <code>bevel</code> value means that this is all that is + rendered at joins.</p> + + <p>The <code>round</code> value means that a filled arc connecting + the two aforementioned corners of the join, abutting (and not + overlapping) the aforementioned triangle, with the diameter equal to + the line width and the origin at the point of the join, must be + rendered at joins.</p> + + <p>The <code>miter</code> value means that a second filled triangle + must (if it can given the miter length) be rendered at the join, + with one line being the line between the two aforementioned corners, + abutting the first triangle, and the other two being continuations of + the outside edges of the two joining lines, as long as required to + intersect without going over the miter length.</p> + + <p>The miter length is the distance from the point where the join + occurs to the intersection of the line edges on the outside of the + join. The miter limit ratio is the maximum allowed ratio of the + miter length to half the line width. If the miter length would cause + the miter limit ratio to be exceeded, this second triangle must not + be rendered.</p> + + <p>The miter limit ratio can be explicitly set using the <dfn id="dom-context-2d-miterlimit" title="dom-context-2d-miterLimit"><code>miterLimit</code></dfn> + attribute. On getting, it must return the current value. On setting, + zero, negative, infinite, and NaN values must be ignored, leaving + the value unchanged; other values must change the current value to + the new value.</p> + + <p>When the context is created, the <code title="dom-context-2d-miterLimit"><a href="#dom-context-2d-miterlimit">miterLimit</a></code> attribute must + initially have the value <code>10.0</code>.</p> + + <!-- +v6: dashed lines have been requested. Philip Taylor provides these +notes on what would need to be defined for dashed lines: +> I don't think it's entirely trivial to add, to the detail that's +> necessary in a specification. The common graphics APIs (at least +> Cairo, Quartz and java.awt.Graphics, and any SVG implementation) all +> have dashes specified by passing an array of dash lengths (alternating +> on/off), so that should be alright as long as you define what units +> it's measured in and what happens when you specify an odd number of +> values and how errors are handled and what happens if you update the +> array later. But after that, what does it do when stroking multiple +> subpaths, in terms of offsetting the dashes? When you use strokeRect, +> where is offset 0? Does moveTo reset the offset? How does it interact +> with lineCap/lineJoin? All the potential issues need test cases too, +> and the implementations need to make sure they handle any edge cases +> that the underlying graphics library does differently. (SVG Tiny 1.2 +> appears to skip some of the problems by leaving things undefined and +> allowing whatever behavior the graphics library has.) + +Another request has been for hairline width lines, that remain +hairline width with transform. ack Shaun Morris. + --> + + </div> + + + <h6 id="shadows"><span class="secno">4.8.11.1.6 </span><dfn>Shadows</dfn></h6> + + <p>All drawing operations are affected by the four global shadow + attributes.</p> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current shadow color.</p> + + <p>Can be set, to change the shadow color. Values that cannot be parsed as CSS colors are ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-shadowOffsetX"><a href="#dom-context-2d-shadowoffsetx">shadowOffsetX</a></code> [ = <var title="">value</var> ]</dt> + <dt><var title="">context</var> . <code title="dom-context-2d-shadowOffsetY"><a href="#dom-context-2d-shadowoffsety">shadowOffsetY</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current shadow offset.</p> + + <p>Can be set, to change the shadow offset. Values that are not finite numbers are ignored.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current level of blur applied to shadows.</p> + + <p>Can be set, to change the blur level. Values that are not finite numbers greater than or equal to zero are ignored.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-shadowcolor" title="dom-context-2d-shadowColor"><code>shadowColor</code></dfn> + attribute sets the color of the shadow.</p> + + <p>When the context is created, the <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code> attribute + initially must be fully-transparent black.</p> + + <p>On getting, the <a href="#serialization-of-a-color" title="serialization of a + color">serialization of the color</a> must be returned.</p> + + <p>On setting, the new value must be <a href="#parsed-as-a-css-color-value">parsed as a CSS + <color> value</a> and the color assigned. If the value + cannot be parsed as a CSS <color> value then it must be + ignored, and the attribute must retain its previous value. <a href="#refsCSSCOLOR">[CSSCOLOR]</a></p> + + <p>The <dfn id="dom-context-2d-shadowoffsetx" title="dom-context-2d-shadowOffsetX"><code>shadowOffsetX</code></dfn> + and <dfn id="dom-context-2d-shadowoffsety" title="dom-context-2d-shadowOffsetY"><code>shadowOffsetY</code></dfn> + attributes specify the distance that the shadow will be offset in + the positive horizontal and positive vertical distance + respectively. Their values are in coordinate space units. They are + not affected by the current transformation matrix.</p> + + <p>When the context is created, the shadow offset attributes must + initially have the value <code>0</code>.</p> + + <p>On getting, they must return their current value. On setting, the + attribute being set must be set to the new value, except if the + value is infinite or NaN, in which case the new value must be + ignored.</p> + + <p>The <dfn id="dom-context-2d-shadowblur" title="dom-context-2d-shadowBlur"><code>shadowBlur</code></dfn> + attribute specifies the level of the blurring effect. (The units do + not map to coordinate space units, and are not affected by the + current transformation matrix.)</p> + + <p>When the context is created, the <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code> attribute must + initially have the value <code>0</code>.</p> + + <p>On getting, the attribute must return its current value. On + setting the attribute must be set to the new value, except if the + value is negative, infinite or NaN, in which case the new value must + be ignored.</p> + + <p><dfn id="when-shadows-are-drawn" title="when shadows are drawn">Shadows are only drawn + if</dfn> the opacity component of the alpha component of the color + of <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code> is + non-zero and either the <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code> is non-zero, or + the <code title="dom-context-2d-shadowOffsetX"><a href="#dom-context-2d-shadowoffsetx">shadowOffsetX</a></code> + is non-zero, or the <code title="dom-context-2d-shadowOffsetY"><a href="#dom-context-2d-shadowoffsety">shadowOffsetY</a></code> is + non-zero.</p> + + <p class="critical">It is likely that this will change: browser + vendors have indicated an interest in changing the processing model + for shadows such that they only draw when the composition operator + is "source-over" (the default). <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-May/thread.html#31457">Read + more...</a></p> + + <p><a href="#when-shadows-are-drawn">When shadows are drawn</a>, they must be rendered as follows:</p> + + <ol><li> <p>Let <var title="">A</var> be an infinite transparent black + bitmap on which the source image for which a shadow is being + created has been rendered.</p> </li> + + <li> <p>Let <var title="">B</var> be an infinite transparent black + bitmap, with a coordinate space and an origin identical to <var title="">A</var>.</p> </li> + + <li> <p>Copy the alpha channel of <var title="">A</var> to <var title="">B</var>, offset by <code title="dom-context-2d-shadowOffsetX"><a href="#dom-context-2d-shadowoffsetx">shadowOffsetX</a></code> in the + positive <var title="">x</var> direction, and <code title="dom-context-2d-shadowOffsetY"><a href="#dom-context-2d-shadowoffsety">shadowOffsetY</a></code> in the + positive <var title="">y</var> direction.</p> </li> + + <li> <p>If <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code> is greater than + 0:</p> + + <ol><li> <p>Let <var title="">σ</var> be half the value of + <code title="dom-context-2d-shadowBlur"><a href="#dom-context-2d-shadowblur">shadowBlur</a></code>.</p></li> + + <li> <p>Perform a 2D Gaussian Blur on <var title="">B</var>, + using <var title="">σ</var> as the standard deviation.</p> + <!-- wish i could find a reference for this --> </li> + + </ol><p>User agents may limit values of <var title="">σ</var> to + an implementation-specific maximum value to avoid exceeding + hardware limitations during the Gaussian blur operation.</p> + + </li> + + <li> <p>Set the red, green, and blue components of every pixel in + <var title="">B</var> to the red, green, and blue components + (respectively) of the color of <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code>.</p> </li> + + <li> <p>Multiply the alpha component of every pixel in <var title="">B</var> by the alpha component of the color of <code title="dom-context-2d-shadowColor"><a href="#dom-context-2d-shadowcolor">shadowColor</a></code>.</p> </li> + + <li> <p>The shadow is in the bitmap <var title="">B</var>, and is + rendered as part of the <a href="#drawing-model">drawing model</a> described below.</p> </li> + + </ol></div> + + <p>If the current composition operation is <code title="gcop-copy"><a href="#gcop-copy">copy</a></code>, shadows effectively won't render + (since the shape will overwrite the shadow).</p> + + + <h6 id="simple-shapes-(rectangles)"><span class="secno">4.8.11.1.7 </span>Simple shapes (rectangles)</h6> + + <p>There are three methods that immediately draw rectangles to the + bitmap. They each take four arguments; the first two give the <var title="">x</var> and <var title="">y</var> coordinates of the top + left of the rectangle, and the second two give the width <var title="">w</var> and height <var title="">h</var> of the rectangle, + respectively.</p> + + <div class="impl"> + + <p>The <a href="#transformations" title="dom-context-2d-transformation">current + transformation matrix</a> must be applied to the following four + coordinates, which form the path that must then be closed to get the + specified rectangle: <span title="">(<var title="">x</var>, <var title="">y</var>)</span>, <span title="">(<span title=""><var title="">x</var>+<var title="">w</var></span>, <var title="">y</var>)</span>, + <span title="">(<span title=""><var title="">x</var>+<var title="">w</var></span>, + <span title=""><var title="">y</var>+<var title="">h</var></span>)</span>, + <span title="">(<var title="">x</var>, <span title=""><var title="">y</var>+<var title="">h</var></span>)</span>.</p> + + <p>Shapes are painted without affecting the current path, and are + subject to the <a href="#clipping-region" title="clipping region">clipping region</a>, + and, with the exception of <code title="dom-context-2d-clearRect"><a href="#dom-context-2d-clearrect">clearRect()</a></code>, also <a href="#shadows" title="shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, and <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>.</p> + + </div> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-clearRect"><a href="#dom-context-2d-clearrect">clearRect</a></code>(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</dt> + + <dd> + + <p>Clears all pixels on the canvas in the given rectangle to transparent black.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-fillRect"><a href="#dom-context-2d-fillrect">fillRect</a></code>(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</dt> + + <dd> + + <p>Paints the given rectangle onto the canvas, using the current fill style.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-strokeRect"><a href="#dom-context-2d-strokerect">strokeRect</a></code>(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</dt> + + <dd> + + <p>Paints the box that outlines the given rectangle onto the canvas, using the current stroke style.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-clearrect" title="dom-context-2d-clearRect"><code>clearRect(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</code></dfn> method must clear the pixels in the + specified rectangle that also intersect the current clipping region + to a fully transparent black, erasing any previous image. If either + height or width are zero, this method has no effect.</p> + + <p>The <dfn id="dom-context-2d-fillrect" title="dom-context-2d-fillRect"><code>fillRect(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</code></dfn> method must paint the specified + rectangular area using the <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code>. If either height + or width are zero, this method has no effect.</p> + + <p>The <dfn id="dom-context-2d-strokerect" title="dom-context-2d-strokeRect"><code>strokeRect(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</code></dfn> method must stroke the specified + rectangle's path using the <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code>, <code title="dom-context-2d-lineWidth"><a href="#dom-context-2d-linewidth">lineWidth</a></code>, <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code>, and (if + appropriate) <code title="dom-context-2d-miterLimit"><a href="#dom-context-2d-miterlimit">miterLimit</a></code> attributes. If + both height and width are zero, this method has no effect, since + there is no path to stroke (it's a point). If only one of the two is + zero, then the method will draw a line instead (the path for the + outline is just a straight line along the non-zero dimension).</p> + + </div> + + + <h6 id="complex-shapes-(paths)"><span class="secno">4.8.11.1.8 </span>Complex shapes (paths)</h6> + + <p>The context always has a current path. There is only one current + path, it is not part of the <a href="#drawing-state">drawing state</a>.</p> + + <p>A <dfn id="path">path</dfn> has a list of zero or more subpaths. Each + subpath consists of a list of one or more points, connected by + straight or curved lines, and a flag indicating whether the subpath + is closed or not. A closed subpath is one where the last point of + the subpath is connected to the first point of the subpath by a + straight line. Subpaths with fewer than two points are ignored when + painting the path.</p> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-beginPath"><a href="#dom-context-2d-beginpath">beginPath</a></code>()</dt> + + <dd> + + <p>Resets the current path.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-moveTo"><a href="#dom-context-2d-moveto">moveTo</a></code>(<var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Creates a new subpath with the given point.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-closePath"><a href="#dom-context-2d-closepath">closePath</a></code>()</dt> + + <dd> + + <p>Marks the current subpath as closed, and starts a new subpath with a point the same as the start and end of the newly closed subpath.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-lineTo"><a href="#dom-context-2d-lineto">lineTo</a></code>(<var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Adds the given point to the current subpath, connected to the previous one by a straight line.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-quadraticCurveTo"><a href="#dom-context-2d-quadraticcurveto">quadraticCurveTo</a></code>(<var title="">cpx</var>, <var title="">cpy</var>, <var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Adds the given point to the current subpath, connected to the previous one by a quadratic Bézier curve with the given control point.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-bezierCurveTo"><a href="#dom-context-2d-beziercurveto">bezierCurveTo</a></code>(<var title="">cp1x</var>, <var title="">cp1y</var>, <var title="">cp2x</var>, <var title="">cp2y</var>, <var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Adds the given point to the current subpath, connected to the previous one by a cubic Bézier curve with the given control points.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-arcTo"><a href="#dom-context-2d-arcto">arcTo</a></code>(<var title="">x1</var>, <var title="">y1</var>, <var title="">x2</var>, <var title="">y2</var>, <var title="">radius</var>)</dt> + + <dd> + + <p>Adds an arc with the given control points and radius to the + current subpath, connected to the previous point by a straight + line.</p> + + <p>Throws an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception if the given + radius is negative.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-arc"><a href="#dom-context-2d-arc">arc</a></code>(<var title="">x</var>, <var title="">y</var>, <var title="">radius</var>, <var title="">startAngle</var>, <var title="">endAngle</var> [, <var title="">anticlockwise</var> ] )</dt> + + <dd> + + <p>Adds points to the subpath such that the arc described by the + circumference of the circle described by the arguments, starting + at the given start angle and ending at the given end angle, going + in the given direction (defaulting to clockwise), is added to the + path, connected to the previous point by a straight line.</p> + + <p>Throws an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception if the given + radius is negative.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-rect"><a href="#dom-context-2d-rect">rect</a></code>(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</dt> + + <dd> + + <p>Adds a new closed subpath to the path, representing the given rectangle.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-fill"><a href="#dom-context-2d-fill">fill</a></code>()</dt> + + <dd> + + <p>Fills the subpaths with the current fill style.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-stroke"><a href="#dom-context-2d-stroke">stroke</a></code>()</dt> + + <dd> + + <p>Strokes the subpaths with the current stroke style.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-drawSystemFocusRing"><a href="#dom-context-2d-drawsystemfocusring">drawSystemFocusRing</a></code>(<var title="">element</var>)</dt> + + <dd> + + <p>If the given element is focused, draws a focus ring around the + current path, following the platform conventions for focus + rings.</p> + + </dd> + + <dt><var title="">shouldDraw</var> = <var title="">context</var> . <code title="dom-context-2d-drawCustomFocusRing"><a href="#dom-context-2d-drawcustomfocusring">drawCustomFocusRing</a></code>(<var title="">element</var>)</dt> + + <dd> + + <p>If the given element is focused, and the user has configured + his system to draw focus rings in a particular manner (for + example, high contrast focus rings), draws a focus ring around the + current path and returns false.</p> + + <p>Otherwise, returns true if the given element is focused, and + false otherwise. This can thus be used to determine when to draw a + focus ring (see <a href="#drawCustomFocusRingExample">the + example</a> below).</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-scrollPathIntoView"><a href="#dom-context-2d-scrollpathintoview">scrollPathIntoView</a></code>()</dt> + + <dd> + + <p>Scrolls the current path into view. This is especially useful + on devices with small screens, where the whole canvas might not be + visible at once.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-clip"><a href="#dom-context-2d-clip">clip</a></code>()</dt> + + <dd> + + <p>Further constrains the clipping region to the given path.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-isPointInPath"><a href="#dom-context-2d-ispointinpath">isPointInPath</a></code>(<var title="">x</var>, <var title="">y</var>)</dt> + + <dd> + + <p>Returns true if the given point is in the current path.</p> + + </dd> + + </dl><div class="impl"> + + <p>Initially, the context's path must have zero subpaths.</p> + + <p>The points and lines added to the path by these methods must be + transformed according to the <a href="#transformations" title="dom-context-2d-transformation">current transformation + matrix</a> as they are added.</p> + + + <p>The <dfn id="dom-context-2d-beginpath" title="dom-context-2d-beginPath"><code>beginPath()</code></dfn> + method must empty the list of subpaths so that the context once + again has zero subpaths.</p> + + + <p>The <dfn id="dom-context-2d-moveto" title="dom-context-2d-moveTo"><code>moveTo(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must + create a new subpath with the specified point as its first (and + only) point.</p> + + <p>When the user agent is to <dfn id="ensure-there-is-a-subpath">ensure there is a subpath</dfn> + for a coordinate (<var title="">x</var>, <var title="">y</var>), the + user agent must check to see if the context has any subpaths, and if + it does not, then the user agent must create a new subpath with the + point (<var title="">x</var>, <var title="">y</var>) as its first + (and only) point, as if the <code title="dom-context-2d-moveTo"><a href="#dom-context-2d-moveto">moveTo()</a></code> method had been + called.</p> + + + <p>The <dfn id="dom-context-2d-closepath" title="dom-context-2d-closePath"><code>closePath()</code></dfn> + method must do nothing if the context has no subpaths. Otherwise, it + must mark the last subpath as closed, create a new subpath whose + first point is the same as the previous subpath's first point, and + finally add this new subpath to the path.</p> + + <p class="note">If the last subpath had more than one point in its + list of points, then this is equivalent to adding a straight line + connecting the last point back to the first point, thus "closing" + the shape, and then repeating the last (possibly implied) <code title="dom-context-2d-moveTo"><a href="#dom-context-2d-moveto">moveTo()</a></code> call.</p> + + + <p>New points and the lines connecting them are added to subpaths + using the methods described below. In all cases, the methods only + modify the last subpath in the context's paths.</p> + + + <p>The <dfn id="dom-context-2d-lineto" title="dom-context-2d-lineTo"><code>lineTo(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must + <a href="#ensure-there-is-a-subpath">ensure there is a subpath</a> for <span title="">(<var title="">x</var>, <var title="">y</var>)</span> if the context has + no subpaths. Otherwise, it must connect the last point in the + subpath to the given point (<var title="">x</var>, <var title="">y</var>) using a straight line, and must then add the given + point (<var title="">x</var>, <var title="">y</var>) to the + subpath.</p> + + + <p>The <dfn id="dom-context-2d-quadraticcurveto" title="dom-context-2d-quadraticCurveTo"><code>quadraticCurveTo(<var title="">cpx</var>, <var title="">cpy</var>, <var title="">x</var>, + <var title="">y</var>)</code></dfn> method must <a href="#ensure-there-is-a-subpath">ensure there + is a subpath</a> for <span title="">(<var title="">cpx</var>, + <var title="">cpy</var>)</span>, and then must connect the last + point in the subpath to the given point (<var title="">x</var>, <var title="">y</var>) using a quadratic Bézier curve with control + point (<var title="">cpx</var>, <var title="">cpy</var>), and must + then add the given point (<var title="">x</var>, <var title="">y</var>) to the subpath. <a href="#refsBEZIER">[BEZIER]</a></p> + + + <p>The <dfn id="dom-context-2d-beziercurveto" title="dom-context-2d-bezierCurveTo"><code>bezierCurveTo(<var title="">cp1x</var>, <var title="">cp1y</var>, <var title="">cp2x</var>, <var title="">cp2y</var>, <var title="">x</var>, <var title="">y</var>)</code></dfn> method must + <a href="#ensure-there-is-a-subpath">ensure there is a subpath</a> for <span title="">(<var title="">cp1x</var>, <var title="">cp1y</var>)</span>, and then must + connect the last point in the subpath to the given point (<var title="">x</var>, <var title="">y</var>) using a cubic Bézier + curve with control points (<var title="">cp1x</var>, <var title="">cp1y</var>) and (<var title="">cp2x</var>, <var title="">cp2y</var>). Then, it must add the point (<var title="">x</var>, <var title="">y</var>) to the subpath. <a href="#refsBEZIER">[BEZIER]</a></p> + + <hr/><p>The <dfn id="dom-context-2d-arcto" title="dom-context-2d-arcTo"><code>arcTo(<var title="">x1</var>, <var title="">y1</var>, <var title="">x2</var>, + <var title="">y2</var>, <var title="">radius</var>)</code></dfn> + method must first <a href="#ensure-there-is-a-subpath">ensure there is a subpath</a> for <span title="">(<var title="">x1</var>, <var title="">y1</var>)</span>. Then, the behavior depends on the + arguments and the last point in the subpath, as described below.</p> + + <p>Negative values for <var title="">radius</var> must cause the + implementation to raise an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> + exception.</p> + + <p>Let the point (<var title="">x0</var>, <var title="">y0</var>) be + the last point in the subpath.</p> + + <p>If the point (<var title="">x0</var>, <var title="">y0</var>) is + equal to the point (<var title="">x1</var>, <var title="">y1</var>), + or if the point (<var title="">x1</var>, <var title="">y1</var>) is + equal to the point (<var title="">x2</var>, <var title="">y2</var>), + or if the radius <var title="">radius</var> is zero, then the method + must add the point (<var title="">x1</var>, <var title="">y1</var>) + to the subpath, and connect that point to the previous point (<var title="">x0</var>, <var title="">y0</var>) by a straight line.</p> + + <p>Otherwise, if the points (<var title="">x0</var>, <var title="">y0</var>), (<var title="">x1</var>, <var title="">y1</var>), and (<var title="">x2</var>, <var title="">y2</var>) all lie on a single straight line, then the + method must add the point (<var title="">x1</var>, <var title="">y1</var>) to the subpath, and connect that point to the + previous point (<var title="">x0</var>, <var title="">y0</var>) by a + straight line.</p> + + <p>Otherwise, let <var title="">The Arc</var> be the shortest arc + given by circumference of the circle that has radius <var title="">radius</var>, and that has one point tangent to the + half-infinite line that crosses the point (<var title="">x0</var>, + <var title="">y0</var>) and ends at the point (<var title="">x1</var>, <var title="">y1</var>), and that has a different + point tangent to the half-infinite line that ends at the point (<var title="">x1</var>, <var title="">y1</var>) and crosses the point + (<var title="">x2</var>, <var title="">y2</var>). The points at + which this circle touches these two lines are called the start and + end tangent points respectively. The method must connect the point + (<var title="">x0</var>, <var title="">y0</var>) to the start + tangent point by a straight line, adding the start tangent point to + the subpath, and then must connect the start tangent point to the + end tangent point by <var title="">The Arc</var>, adding the end + tangent point to the subpath.</p> + + <hr/><p>The <dfn id="dom-context-2d-arc" title="dom-context-2d-arc"><code>arc(<var title="">x</var>, <var title="">y</var>, <var title="">radius</var>, + <var title="">startAngle</var>, <var title="">endAngle</var>, <var title="">anticlockwise</var>)</code></dfn> method draws an arc. If + the context has any subpaths, then the method must add a straight + line from the last point in the subpath to the start point of the + arc. In any case, it must draw the arc between the start point of + the arc and the end point of the arc, and add the start and end + points of the arc to the subpath. The arc and its start and end + points are defined as follows:</p> + + <p>Consider a circle that has its origin at (<var title="">x</var>, + <var title="">y</var>) and that has radius <var title="">radius</var>. The points at <var title="">startAngle</var> + and <var title="">endAngle</var> along this circle's circumference, + measured in radians clockwise from the positive x-axis, are the + start and end points respectively.</p> + + <p>If the <var title="">anticlockwise</var> argument is omitted or + false and <span title=""><var title="">endAngle</var>-<var title="">startAngle</var></span> is equal to or greater than <span title="">2π</span>, or, if the <var title="">anticlockwise</var> + argument is <em>true</em> and <span title=""><var title="">startAngle</var>-<var title="">endAngle</var></span> is + equal to or greater than <span title="">2π</span>, then the arc + is the whole circumference of this circle.</p> + + <p>Otherwise, the arc is the path along the circumference of this + circle from the start point to the end point, going anti-clockwise + if the <var title="">anticlockwise</var> argument is true, and + clockwise otherwise. Since the points are on the circle, as opposed + to being simply angles from zero, the arc can never cover an angle + greater than <span title="">2π</span> radians. If the two points are the + same, or if the radius is zero, then the arc is defined as being of + zero length in both directions.</p> + + <p>Negative values for <var title="">radius</var> must cause the + implementation to raise an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> + exception.</p> + + <hr/><p>The <dfn id="dom-context-2d-rect" title="dom-context-2d-rect"><code>rect(<var title="">x</var>, <var title="">y</var>, <var title="">w</var>, <var title="">h</var>)</code></dfn> method must create a new subpath + containing just the four points (<var title="">x</var>, <var title="">y</var>), (<var title="">x</var>+<var title="">w</var>, + <var title="">y</var>), (<var title="">x</var>+<var title="">w</var>, <var title="">y</var>+<var title="">h</var>), + (<var title="">x</var>, <var title="">y</var>+<var title="">h</var>), with those four points connected by straight + lines, and must then mark the subpath as closed. It must then create + a new subpath with the point (<var title="">x</var>, <var title="">y</var>) as the only point in the subpath.</p> + + + <!-- v6 feature request: + * points as a primitive shape + http://home.comcast.net/~urbanjost/canvas/vogle4.html + --> + + + <p>The <dfn id="dom-context-2d-fill" title="dom-context-2d-fill"><code>fill()</code></dfn> + method must fill all the subpaths of the current path, using + <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code>, and using + the non-zero winding number rule. Open subpaths must be implicitly + closed when being filled (without affecting the actual + subpaths).</p> + + <p class="note">Thus, if two overlapping but otherwise independent + subpaths have opposite windings, they cancel out and result in no + fill. If they have the same winding, that area just gets painted + once.</p> + + <p>The <dfn id="dom-context-2d-stroke" title="dom-context-2d-stroke"><code>stroke()</code></dfn> method + must calculate the strokes of all the subpaths of the current path, + using the <code title="dom-context-2d-lineWidth"><a href="#dom-context-2d-linewidth">lineWidth</a></code>, + <code title="dom-context-2d-lineCap"><a href="#dom-context-2d-linecap">lineCap</a></code>, <code title="dom-context-2d-lineJoin"><a href="#dom-context-2d-linejoin">lineJoin</a></code>, and (if + appropriate) <code title="dom-context-2d-miterLimit"><a href="#dom-context-2d-miterlimit">miterLimit</a></code> attributes, and + then fill the combined stroke area using the <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> + attribute.</p> + + <p class="note">Since the subpaths are all stroked as one, + overlapping parts of the paths in one stroke operation are treated + as if their union was what was painted.</p> + + <p>Paths, when filled or stroked, must be painted without affecting + the current path, and must be subject to <a href="#shadows" title="shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, the <a href="#clipping-region" title="clipping region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>. (Transformations affect the path when the path is + created, not when it is painted, though the stroke <em>style</em> is + still affected by the transformation during painting.)</p> + + <p>Zero-length line segments must be pruned before stroking a + path. Empty subpaths must be ignored.</p> + + <hr/><p id="dom-context-2d-drawosfocusring">The <dfn id="dom-context-2d-drawsystemfocusring" title="dom-context-2d-drawSystemFocusRing"><code>drawSystemFocusRing(<var title="">element</var>)</code></dfn> method, when invoked, must run + the following steps:</p> + + <ol><li><p>If <var title="">element</var> is not focused or is not a + descendant of the element with whose context the method is + associated, then abort these steps.</p></li> + + <li> + + <p>If the user has requested the use of particular focus rings + (e.g. high-contrast focus rings), or if the <var title="">element</var> would have a focus ring drawn around it, + then draw a focus ring of the appropriate style along the path, + following platform conventions, and abort these steps.</p> + + <p class="note">Some platforms only draw focus rings around + elements that have been focused from the keyboard, and not those + focused from the mouse. Other platforms simply don't draw focus + rings around some elements at all unless relevant accessibility + features are enabled. This API is intended to follow these + conventions. User agents that implement distinctions based on the + manner in which the element was focused are encouraged to classify + focus driven by the <code title="dom-focus"><a href="#dom-focus">focus()</a></code> method + based on the kind of user interaction event from which the call + was triggered (if any).</p> + + <p>The focus ring should not be subject to the <a href="#shadows" title="shadows">shadow effects</a>, the <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, or the <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>, but <em>should</em> be subject to the <a href="#clipping-region" title="clipping region">clipping region</a>.</p> + + </li> + + <li> + + <p>Optionally, <a href="#inform">inform the user</a> that the + focus is at the location given by the path. User agents may wait + until the next time the <a href="#event-loop">event loop</a> reaches its + "update the rendering" step to optionally inform the user.</p> + + </li> + + </ol><p>The <dfn id="dom-context-2d-drawcustomfocusring" title="dom-context-2d-drawCustomFocusRing"><code>drawCustomFocusRing(<var title="">element</var>)</code></dfn> method, when invoked, must run + the following steps:</p> + + <ol><li><p>If <var title="">element</var> is not focused or is not a + descendant of the element with whose context the method is + associated, then return false and abort these steps.</p></li> + + <li> + + <p>If the user has requested the use of particular focus rings + (e.g. high-contrast focus rings), then draw a focus ring of the + appropriate style along the path, return false, and abort these + steps.</p> + + <p>The focus ring should not be subject to the <a href="#shadows" title="shadows">shadow effects</a>, the <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, or the <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>, but <em>should</em> be subject to the <a href="#clipping-region" title="clipping region">clipping region</a>.</p> + + </li> + + <li> + + <p>Optionally, <a href="#inform">inform the user</a> that the + focus is at the location given by the path. User agents may wait + until the next time the <a href="#event-loop">event loop</a> reaches its + "update the rendering" step to optionally inform the user.</p> + + </li> + + <li><p>Return true.</p></li> + + </ol><p>The <dfn id="dom-context-2d-scrollpathintoview" title="dom-context-2d-scrollPathIntoView"><code>scrollPathIntoView()</code></dfn> + method, when invoked, must run the following steps:</p> + + <ol><li><p>Let <var title="">notional child</var> be a hypothetical + element that is a rendered child of the <code><a href="#the-canvas-element">canvas</a></code> element + whose dimensions are exactly the rectangle of the bounding box of + the current path.</p></li> + + <li><p><span title="scroll an element into view">Scroll <var title="">notional child</var> into view</span> with the <var title="">align to top flag</var> set.</p> + + </li><li><p>Optionally, <a href="#inform">inform the user</a> that the + caret and/or selection cover <var title="">the specified + rectangle</var> of the canvas. User agents may wait until the next + time the <a href="#event-loop">event loop</a> reaches its "update the rendering" + step to optionally inform the user.</p></li> + + </ol><p class="note" id="inform">"Inform the user", as used in this + section, could mean calling a system accessibility API, which would + notify assistive technologies such as magnification tools. To + properly drive magnification based on a focus change, a system + accessibility API driving a screen magnifier needs the bounds for + the newly focused object. The methods above are intended to enable + this by allowing the user agent to report the bounding box of the + path used to render the focus ring as the bounds of the <var title="">element</var> element passed as an argument, if that + element is focused, and the bounding box of the area to which the + user agent is scrolling as the bounding box of the current + selection.</p> + + <hr/><p>The <dfn id="dom-context-2d-clip" title="dom-context-2d-clip"><code>clip()</code></dfn> + method must create a new <dfn id="clipping-region">clipping region</dfn> by calculating + the intersection of the current clipping region and the area + described by the current path, using the non-zero winding number + rule. Open subpaths must be implicitly closed when computing the + clipping region, without affecting the actual subpaths. The new + clipping region replaces the current clipping region.</p> + + <p>When the context is initialized, the clipping region must be set + to the rectangle with the top left corner at (0,0) and the width and + height of the coordinate space.</p> + + <!-- v6 + Jordan OSETE suggests: + * support ways of extending the clipping region (union instead of intersection) + - also "add", "subtract", "replace", "intersect" and "xor" + * support ways of resetting the clipping region without save/restore + --> + + <hr/><p>The <dfn id="dom-context-2d-ispointinpath" title="dom-context-2d-isPointInPath"><code>isPointInPath(<var title="">x</var>, <var title="">y</var>)</code></dfn> method must + return true if the point given by the <var title="">x</var> and <var title="">y</var> coordinates passed to the method, when treated as + coordinates in the canvas coordinate space unaffected by the current + transformation, is inside the current path as determined by the + non-zero winding number rule; and must return false + otherwise. Points on the path itself are considered to be inside the + path. If either of the arguments is infinite or NaN, then the method + must return false.</p> + + </div> + + + <div class="example" id="drawCustomFocusRingExample"> + + <p>This <code><a href="#the-canvas-element">canvas</a></code> element has a couple of checkboxes. The + path-related commands are highlighted:</p> + + <pre><canvas height=400 width=750> + <label><input type=checkbox id=showA> Show As</label> + <label><input type=checkbox id=showB> Show Bs</label> + <!-- ... --> +</canvas> +<script> + function drawCheckbox(context, element, x, y, paint) { + context.save(); + context.font = '10px sans-serif'; + context.textAlign = 'left'; + context.textBaseline = 'middle'; + var metrics = context.measureText(element.labels[0].textContent); + if (paint) { +<strong> context.beginPath(); + context.strokeStyle = 'black'; + context.rect(x-5, y-5, 10, 10); + context.stroke(); +</strong> if (element.checked) { +<strong> context.fillStyle = 'black'; + context.fill(); +</strong> } + context.fillText(element.labels[0].textContent, x+5, y); + } +<strong> context.beginPath(); + context.rect(x-7, y-7, 12 + metrics.width+2, 14); + if (paint && context.drawCustomFocusRing(element)) { + context.strokeStyle = 'silver'; + context.stroke(); + } +</strong> context.restore(); + } + function drawBase() { /* ... */ } + function drawAs() { /* ... */ } + function drawBs() { /* ... */ } + function redraw() { + var canvas = document.getElementsByTagName('canvas')[0]; + var context = canvas.getContext('2d'); + context.clearRect(0, 0, canvas.width, canvas.height); + drawCheckbox(context, document.getElementById('showA'), 20, 40, true); + drawCheckbox(context, document.getElementById('showB'), 20, 60, true); + drawBase(); + if (document.getElementById('showA').checked) + drawAs(); + if (document.getElementById('showB').checked) + drawBs(); + } + function processClick(event) { + var canvas = document.getElementsByTagName('canvas')[0]; + var context = canvas.getContext('2d'); + var x = event.clientX; + var y = event.clientY; + while (node) { + x -= node.offsetLeft - node.scrollLeft; + y -= node.offsetTop - node.scrollTop; + node = node.offsetParent; + } + drawCheckbox(context, document.getElementById('showA'), 20, 40, false); + if (<strong>context.isPointInPath(x, y)</strong>) + document.getElementById('showA').checked = !(document.getElementById('showA').checked); + drawCheckbox(context, document.getElementById('showB'), 20, 60, false); + if (<strong>context.isPointInPath(x, y)</strong>) + document.getElementById('showB').checked = !(document.getElementById('showB').checked); + redraw(); + } + document.getElementsByTagName('canvas')[0].addEventListener('focus', redraw, true); + document.getElementsByTagName('canvas')[0].addEventListener('blur', redraw, true); + document.getElementsByTagName('canvas')[0].addEventListener('change', redraw, true); + document.getElementsByTagName('canvas')[0].addEventListener('click', processClick, false); + redraw(); +</script></pre> +<!-- http://software.hixie.ch/utilities/js/live-dom-viewer/saved/340 --> + + </div> + + + + + <h6 id="text-0"><span class="secno">4.8.11.1.9 </span>Text</h6> <!-- a v3 feature --> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current font settings.</p> + + <p>Can be set, to change the font. The syntax is the same as for + the CSS 'font' property; values that cannot be parsed as CSS font + values are ignored.</p> + + <p>Relative keywords and lengths are computed relative to the font + of the <code><a href="#the-canvas-element">canvas</a></code> element.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current text alignment settings.</p> + + <p>Can be set, to change the alignment. The possible values are + <code title="">start</code>, <code title="">end</code>, <code title="">left</code>, <code title="">right</code>, and <code title="">center</code>. Other values are ignored. The default is + <code title="">start</code>.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> [ = <var title="">value</var> ]</dt> + + <dd> + + <p>Returns the current baseline alignment settings.</p> + + <p>Can be set, to change the baseline alignment. The possible + values and their meanings are given below. Other values are + ignored. The default is <code title="">alphabetic</code>.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-fillText"><a href="#dom-context-2d-filltext">fillText</a></code>(<var title="">text</var>, <var title="">x</var>, <var title="">y</var> [, <var title="">maxWidth</var> ] )</dt> + <dt><var title="">context</var> . <code title="dom-context-2d-strokeText"><a href="#dom-context-2d-stroketext">strokeText</a></code>(<var title="">text</var>, <var title="">x</var>, <var title="">y</var> [, <var title="">maxWidth</var> ] )</dt> + + <dd> + + <p>Fills or strokes (respectively) the given text at the given + position. If a maximum width is provided, the text will be scaled + to fit that width if necessary.</p> + + </dd> + + <dt><var title="">metrics</var> = <var title="">context</var> . <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText</a></code>(<var title="">text</var>)</dt> + + <dd> + + <p>Returns a <code><a href="#textmetrics">TextMetrics</a></code> object with the metrics of the given text in the current font.</p> + + </dd> + + <dt><var title="">metrics</var> . <code title="dom-textmetrics-width"><a href="#dom-textmetrics-width">width</a></code></dt> + + <dd> + + <p>Returns the advance width of the text that was passed to the + <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText()</a></code> + method.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-font" title="dom-context-2d-font"><code>font</code></dfn> IDL + attribute, on setting, must be parsed the same way as the 'font' + property of CSS (but without supporting property-independent style + sheet syntax like 'inherit'), and the resulting font must be + assigned to the context, with the 'line-height' component forced to + 'normal', with the 'font-size' component converted to CSS pixels, + and with system fonts being computed to explicit values. If the new + value is syntactically incorrect (including using + property-independent style sheet syntax like 'inherit' or + 'initial'), then it must be ignored, without assigning a new font + value. <a href="#refsCSS">[CSS]</a></p> + + <p>Font names must be interpreted in the context of the + <code><a href="#the-canvas-element">canvas</a></code> element's stylesheets; any fonts embedded using + <code title="">@font-face</code> must therefore be available once + they are loaded. (If a font is referenced before it is fully loaded, + then it must be treated as if it was an unknown font, falling back + to another as described by the relevant CSS specifications.) <a href="#refsCSSFONTS">[CSSFONTS]</a></p> + + <p>Only vector fonts should be used by the user agent; if a user + agent were to use bitmap fonts then transformations would likely + make the font look very ugly.</p> + + <p>On getting, the <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code> + attribute must return the <span title="serializing a CSS + value">serialized form</span> of the current font of the context + (with no 'line-height' component). <a href="#refsCSSOM">[CSSOM]</a></p> + + <div class="example"> + + <p>For example, after the following statement:</p> + + <pre>context.font = 'italic 400 12px/2 Unknown Font, sans-serif';</pre> + + <p>...the expression <code title="">context.font</code> would + evaluate to the string "<code title="">italic 12px "Unknown Font", sans-serif</code>". The + "400" font-weight doesn't appear because that is the default + value. The line-height doesn't appear because it is forced to + "normal", the default value.</p> + + </div> + + <p>When the context is created, the font of the context must be set + to 10px sans-serif. When the 'font-size' component is set to lengths + using percentages, 'em' or 'ex' units, or the 'larger' or 'smaller' + keywords, these must be interpreted relative to the computed value + of the 'font-size' property of the corresponding <code><a href="#the-canvas-element">canvas</a></code> + element at the time that the attribute is set. When the + 'font-weight' component is set to the relative values 'bolder' and + 'lighter', these must be interpreted relative to the computed value + of the 'font-weight' property of the corresponding + <code><a href="#the-canvas-element">canvas</a></code> element at the time that the attribute is + set. If the computed values are undefined for a particular case + (e.g. because the <code><a href="#the-canvas-element">canvas</a></code> element is not <a href="#in-a-document">in a + <code>Document</code></a>), then the relative keywords must be + interpreted relative to the normal-weight 10px sans-serif + default.</p> + + <p>The <dfn id="dom-context-2d-textalign" title="dom-context-2d-textAlign"><code>textAlign</code></dfn> IDL + attribute, on getting, must return the current value. On setting, if + the value is one of <code title="">start</code>, <code title="">end</code>, <code title="">left</code>, <code title="">right</code>, or <code title="">center</code>, then the + value must be changed to the new value. Otherwise, the new value + must be ignored. When the context is created, the <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> attribute must + initially have the value <code title="">start</code>.</p> + + <p>The <dfn id="dom-context-2d-textbaseline" title="dom-context-2d-textBaseline"><code>textBaseline</code></dfn> + IDL attribute, on getting, must return the current value. On + setting, if the value is one of <code title="dom-context-2d-textBaseline-top"><a href="#dom-context-2d-textbaseline-top">top</a></code>, <code title="dom-context-2d-textBaseline-hanging"><a href="#dom-context-2d-textbaseline-hanging">hanging</a></code>, <code title="dom-context-2d-textBaseline-middle"><a href="#dom-context-2d-textbaseline-middle">middle</a></code>, <code title="dom-context-2d-textBaseline-alphabetic"><a href="#dom-context-2d-textbaseline-alphabetic">alphabetic</a></code>, + <code title="dom-context-2d-textBaseline-ideographic"><a href="#dom-context-2d-textbaseline-ideographic">ideographic</a></code>, + or <code title="dom-context-2d-textBaseline-bottom"><a href="#dom-context-2d-textbaseline-bottom">bottom</a></code>, + then the value must be changed to the new value. Otherwise, the new + value must be ignored. When the context is created, the <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> attribute + must initially have the value <code title="">alphabetic</code>.</p> + + </div> + + <p>The <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> + attribute's allowed keywords correspond to alignment points in the + font:</p> + + <p><img alt="The top of the em square is roughly at the top of the glyphs in a font, the hanging baseline is where some glyphs like आ are anchored, the middle is half-way between the top of the em square and the bottom of the em square, the alphabetic baseline is where characters like Á, ÿ, f, and Ω are anchored, the ideographic baseline is where glyphs like 私 and 達 are anchored, and the bottom of the em square is roughly at the bottom of the glyphs in a font. The top and bottom of the bounding box can be far from these baselines, due to glyphs extending far outside the em square." height="300" src="http://www.whatwg.org/specs/web-apps/current-work/http://images.whatwg.org/baselines.png" width="738"/></p> + + <p>The keywords map to these alignment points as follows:</p> + + <dl><dt><dfn id="dom-context-2d-textbaseline-top" title="dom-context-2d-textBaseline-top"><code>top</code></dfn> + </dt><dd>The top of the em square</dd> + + <dt><dfn id="dom-context-2d-textbaseline-hanging" title="dom-context-2d-textBaseline-hanging"><code>hanging</code></dfn> + </dt><dd>The hanging baseline</dd> + + <dt><dfn id="dom-context-2d-textbaseline-middle" title="dom-context-2d-textBaseline-middle"><code>middle</code></dfn> + </dt><dd>The middle of the em square</dd> + + <dt><dfn id="dom-context-2d-textbaseline-alphabetic" title="dom-context-2d-textBaseline-alphabetic"><code>alphabetic</code></dfn> + </dt><dd>The alphabetic baseline</dd> + + <dt><dfn id="dom-context-2d-textbaseline-ideographic" title="dom-context-2d-textBaseline-ideographic"><code>ideographic</code></dfn> + </dt><dd>The ideographic baseline</dd> + + <dt><dfn id="dom-context-2d-textbaseline-bottom" title="dom-context-2d-textBaseline-bottom"><code>bottom</code></dfn> + </dt><dd>The bottom of the em square</dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-filltext" title="dom-context-2d-fillText"><code>fillText()</code></dfn> and + <dfn id="dom-context-2d-stroketext" title="dom-context-2d-strokeText"><code>strokeText()</code></dfn> + methods take three or four arguments, <var title="">text</var>, <var title="">x</var>, <var title="">y</var>, and optionally <var title="">maxWidth</var>, and render the given <var title="">text</var> at the given (<var title="">x</var>, <var title="">y</var>) coordinates ensuring that the text isn't wider + than <var title="">maxWidth</var> if specified, using the current + <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code>, <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code>, and <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> + values. Specifically, when the methods are called, the user agent + must run the following steps:</p> + + <ol><li><p>If <var title="">maxWidth</var> is present but less than or + equal to zero, return without doing anything; abort these + steps.</p></li> + + <li><p>Let <var title="">font</var> be the current font of the + context, as given by the <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code> attribute.</p></li> + + <li><p>Replace all the <a href="#space-character" title="space character">space + characters</a> in <var title="">text</var> with U+0020 SPACE + characters.</p></li> + + <li><p>Form a hypothetical infinitely wide CSS line box containing + a single inline box containing the text <var title="">text</var>, + with all the properties at their initial values except the 'font' + property of the inline box set to <var title="">font</var>, the + 'direction' property of the inline box set to <a href="#the-directionality">the + directionality</a> of the <code><a href="#the-canvas-element">canvas</a></code> element, and the + 'white-space' property set to 'pre'. <a href="#refsCSS">[CSS]</a></p></li> + + <!-- if you insert a step here, make sure to adjust the next step's + final words --> + + <li><p>If the <var title="">maxWidth</var> argument was specified + and the hypothetical width of the inline box in the hypothetical + line box is greater than <var title="">maxWidth</var> CSS pixels, + then change <var title="">font</var> to have a more condensed font + (if one is available or if a reasonably readable one can be + synthesized by applying a horizontal scale factor to the font) or a + smaller font, and return to the previous step.</p></li> + + <li> + + <p>Let the <var title="">anchor point</var> be a point on the + inline box, determined by the <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> and <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> values, as + follows:</p> + + <p>Horizontal position:</p> + + <dl><dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">left</code></dt> + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">start</code> and <a href="#the-directionality">the directionality</a> of the + <code><a href="#the-canvas-element">canvas</a></code> element is 'ltr'</dt> + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">end</code> and <a href="#the-directionality">the directionality</a> of the + <code><a href="#the-canvas-element">canvas</a></code> element is 'rtl'</dt> + + <dd>Let the <var title="">anchor point</var>'s horizontal + position be the left edge of the inline box.</dd> + + + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">right</code></dt> + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">end</code> and <a href="#the-directionality">the directionality</a> of the + <code><a href="#the-canvas-element">canvas</a></code> element is 'ltr'</dt> + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">start</code> and <a href="#the-directionality">the directionality</a> of the + <code><a href="#the-canvas-element">canvas</a></code> element is 'rtl'</dt> + + <dd>Let the <var title="">anchor point</var>'s horizontal + position be the right edge of the inline box.</dd> + + + <dt> If <code title="dom-context-2d-textAlign"><a href="#dom-context-2d-textalign">textAlign</a></code> is <code title="">center</code></dt> + + <dd>Let the <var title="">anchor point</var>'s horizontal + position be half way between the left and right edges of the + inline box.</dd> + + </dl><p>Vertical position:</p> + + <dl><dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-top"><a href="#dom-context-2d-textbaseline-top">top</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be the top of the em box of the first available font of the + inline box.</dd> + + + <dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-hanging"><a href="#dom-context-2d-textbaseline-hanging">hanging</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be the hanging baseline of the first available font of the inline + box.</dd> + + + <dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-middle"><a href="#dom-context-2d-textbaseline-middle">middle</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be half way between the bottom and the top of the em box of the + first available font of the inline box.</dd> + + + <dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-alphabetic"><a href="#dom-context-2d-textbaseline-alphabetic">alphabetic</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be the alphabetic baseline of the first available font of the inline + box.</dd> + + + <dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-ideographic"><a href="#dom-context-2d-textbaseline-ideographic">ideographic</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be the ideographic baseline of the first available font of the inline + box.</dd> + + + <dt> If <code title="dom-context-2d-textBaseline"><a href="#dom-context-2d-textbaseline">textBaseline</a></code> is <code title="dom-context-2d-textBaseline-bottom"><a href="#dom-context-2d-textbaseline-bottom">bottom</a></code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be the bottom of the em box of the first available font of the + inline box.</dd> + + </dl></li> + + <li> + + <p>Paint the hypothetical inline box as the shape given by the + text's glyphs, as transformed by the <a href="#transformations" title="dom-context-2d-transformation">current transformation + matrix</a>, and anchored and sized so that before applying the + <a href="#transformations" title="dom-context-2d-transformation">current transformation + matrix</a>, the <var title="">anchor point</var> is at (<var title="">x</var>, <var title="">y</var>) and each CSS pixel is + mapped to one coordinate space unit.</p> + + <p>For <code title="dom-context-2d-fillText"><a href="#dom-context-2d-filltext">fillText()</a></code> + <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> must be + applied to the glyphs and <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> must be + ignored. For <code title="dom-context-2d-strokeText"><a href="#dom-context-2d-stroketext">strokeText()</a></code> the reverse + holds and <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> must be + applied to the glyph outlines and <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> must be + ignored.</p> + + <p>Text is painted without affecting the current path, and is + subject to <a href="#shadows" title="shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, the <a href="#clipping-region" title="clipping region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>.</p> + + </li> + + </ol><!--v6DVT - this is commented out until CSS can get its act together +enough to actual specify vertical text rendering (how long have we +been waiting now?) + +WHEN EDITING THIS, FIX THE PARTS MARKED "XXX" BELOW + + <p>The <dfn + title="dom-context-2d-fillVerticalText"><code>fillVerticalText()</code></dfn> + and <dfn + title="dom-context-2d-strokeVerticalText"><code>strokeVerticalText()</code></dfn> + methods take three or four arguments, <var title="">text</var>, <var + title="">x</var>, <var title="">y</var>, and optionally <var + title="">maxHeight</var>, and render the given <var + title="">text</var> as vertical text at the given (<var + title="">x</var>, <var title="">y</var>) coordinates ensuring that + the text isn't taller than <var title="">maxHeight</var> if + specified, using the current <code + title="dom-context-2d-font">font</code> and <code + title="dom-context-2d-textAlign">textAlign</code> + values. Specifically, when the methods are called, the user agent + must run the following steps:</p> + + <ol> + + <li><p>If <var title="">maxHeight</var> is present but less than or + equal to zero, return without doing anything; abort these + steps.</p></li> + + <li><p>Let <var title="">font</var> be the current font of the + context, as given by the <code + title="dom-context-2d-font">font</code> attribute.</p></li> + + <li><p>Replace all the <span title="space character">space + characters</span> in <var title="">text</var> with U+0020 SPACE + characters.</p></li> + + <li><p>Form a <em class="XXX">whatever CSS ends up calling + vertical line boxes and inline boxes</em> containing the text <var + title="">text</var>, with all the properties at their initial + values except the 'font' property of the inline box set to <var + title="">font</var> and the 'direction' property of the inline + box set to <span>the directionality</span> of the <code>canvas</code> + element.</p></li> + + <!- - if you insert a step here, make sure to adjust the next step's + final words - -> + + <li><p>If the <var title="">maxHeight</var> argument was specified + and the hypothetical height of the <em class="XXX">box</em> + in the hypothetical line box is greater than <var + title="">maxHeight</var> CSS pixels, then change <var + title="">font</var> to have a more condensed font (if one is + available or if a reasonably readable one can be synthesized by + applying an appropriate scale factor to the font) or a smaller + font, and return to the previous step.</p></li> + + <li> + + <p>Let the <var title="">anchor point</var> be a point on the <em + class="XXX">inline box</var>, determined by the <code + title="dom-context-2d-textAlign">textAlign</code>, as follows:</p> + + <p>Vertical position:</p> + + <dl> + + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">start</code></dt> + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">left</code> and <span>the directionality</span> of the + <code>canvas</code> element is 'ltr'</dt> + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">right</code> and <span>the directionality</span> of the + <code>canvas</code> element is 'rtl'</dt> + + <dd>Let the <var title="">anchor point</var>'s vertical + position be the top edge of the <em class="XXX">inline + box</em>.</dd> + + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">end</code></dt> + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">right</code> and <span>the directionality</span> of the + <code>canvas</code> element is 'ltr'</dt> + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">left</code> and <span>the directionality</span> of the + <code>canvas</code> element is 'rtl'</dt> + + <dd>Let the <var title="">anchor point</var>'s vertical + position be the bottom edge of the <em class="XXX">inline + box</em>.</dd> + + + <dt> If <code + title="dom-context-2d-textAlign">textAlign</code> is <code + title="">center</code></dt> + + <dd>Let the <var title="">anchor point</var>'s vertical position + be half way between the top and bottom edges of the <em + class="XXX">inline box</em>.</dd> + + </dl> + + <p>Let the horizontal position be half way between the left and + right edges of the em box of the first available font of the <em + class="XXX">inline box</em>.</p> + + </li> + + <li> + + <p>Paint the hypothetical inline box as the shape given by the + text's glyphs, as transformed by the <span + title="dom-context-2d-transformation">current transformation + matrix</span>, and anchored and sized so that before applying the + <span title="dom-context-2d-transformation">current transformation + matrix</span>, the <var title="">anchor point</var> is at (<var + title="">x</var>, <var title="">y</var>) and each CSS pixel is + mapped to one coordinate space unit.</p> + + <p>For <code + title="dom-context-2d-fillVerticalText">fillVerticalText()</code> + <code title="dom-context-2d-fillStyle">fillStyle</code> must be + applied and <code + title="dom-context-2d-strokeStyle">strokeStyle</code> must be + ignored. For <code + title="dom-context-2d-strokeVerticalText">strokeVerticalText()</code> + the reverse holds and <code + title="dom-context-2d-strokeStyle">strokeStyle</code> must be + applied and <code + title="dom-context-2d-fillStyle">fillStyle</code> must be + ignored.</p> + + <p>Text is painted without affecting the current path, and is + subject to <span title="shadows">shadow effects</span>, <span + title="dom-context-2d-globalAlpha">global alpha</span>, the <span + title="clipping region">clipping region</span>, and <span + title="dom-context-2d-globalCompositeOperation">global composition + operators</span>.</p> + + </li> + + </ol> + +v6DVT (also check for '- -' bits in the part above) --><p>The <dfn id="dom-context-2d-measuretext" title="dom-context-2d-measureText"><code>measureText()</code></dfn> + method takes one argument, <var title="">text</var>. When the method + is invoked, the user agent must replace all the <a href="#space-character" title="space + character">space characters</a> in <var title="">text</var> with + U+0020 SPACE characters, and then must form a hypothetical + infinitely wide CSS line box containing a single inline box + containing the text <var title="">text</var>, with all the + properties at their initial values except the 'white-space' property + of the inline element set to 'pre' and the 'font' property of the + inline element set to the current font of the context as given by + the <code title="dom-context-2d-font"><a href="#dom-context-2d-font">font</a></code> attribute, and + must then return a new <code><a href="#textmetrics">TextMetrics</a></code> object with its + <code title="dom-textmetrics-width"><a href="#dom-textmetrics-width">width</a></code> attribute set to + the width of that inline box, in CSS pixels. <a href="#refsCSS">[CSS]</a></p> + + <p>The <code><a href="#textmetrics">TextMetrics</a></code> interface is used for the objects + returned from <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText()</a></code>. It has one + attribute, <dfn id="dom-textmetrics-width" title="dom-textmetrics-width"><code>width</code></dfn>, which is set + by the <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText()</a></code> + method.</p> + + <p class="note">Glyphs rendered using <code title="dom-context-2d-fillText"><a href="#dom-context-2d-filltext">fillText()</a></code> and <code title="dom-context-2d-strokeText"><a href="#dom-context-2d-stroketext">strokeText()</a></code> can spill out + of the box given by the font size (the em square size) and the width + returned by <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText()</a></code> (the text + width). This version of the specification does not provide a way to + obtain the bounding box dimensions of the text. If the text is to be + rendered and removed, care needs to be taken to replace the entire + area of the canvas that the clipping region covers, not just the box + given by the em square height and measured text width.</p> + + <!-- v6: Drawing text along a given path --> + <!-- v6: Adding text to a path --> + <!-- see also: http://www.w3.org/TR/SVG11/text.html#TextpathLayoutRules --> + <!-- see also: http://developer.mozilla.org/en/docs/Drawing_text_using_a_canvas --> + + </div> + + <p class="note">A future version of the 2D context API may provide a + way to render fragments of documents, rendered using CSS, straight + to the canvas. This would be provided in preference to a dedicated + way of doing multiline layout.</p> + + + + <h6 id="images"><span class="secno">4.8.11.1.10 </span>Images</h6> + + <p>To draw images onto the canvas, the <dfn id="dom-context-2d-drawimage" title="dom-context-2d-drawImage"><code>drawImage</code></dfn> method + can be used.</p> + + <p>This method can be invoked with three different sets of arguments:</p> + + <ul class="brief"><li><code title="">drawImage(<var title="">image</var>, <var title="">dx</var>, <var title="">dy</var>)</code> + </li><li><code title="">drawImage(<var title="">image</var>, <var title="">dx</var>, <var title="">dy</var>, <var title="">dw</var>, <var title="">dh</var>)</code> + </li><li><code title="">drawImage(<var title="">image</var>, <var title="">sx</var>, <var title="">sy</var>, <var title="">sw</var>, <var title="">sh</var>, <var title="">dx</var>, <var title="">dy</var>, <var title="">dw</var>, <var title="">dh</var>)</code> + </li></ul><!-- v3: drawImage() of an ImageData object might make sense (when resizing as well as filtering) - ack Charles Pritchard --><p>Each of those three can take either an + <code><a href="#htmlimageelement">HTMLImageElement</a></code>, an <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, or + an <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> for the <var title="">image</var> + argument.</p> + + <dl class="domintro"><dt><var title="">context</var> . <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var title="">image</var>, <var title="">dx</var>, <var title="">dy</var>)</dt> + <dt><var title="">context</var> . <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var title="">image</var>, <var title="">dx</var>, <var title="">dy</var>, <var title="">dw</var>, <var title="">dh</var>)</dt> + <dt><var title="">context</var> . <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage</a></code>(<var title="">image</var>, <var title="">sx</var>, <var title="">sy</var>, <var title="">sw</var>, <var title="">sh</var>, <var title="">dx</var>, <var title="">dy</var>, <var title="">dw</var>, <var title="">dh</var>)</dt> + + <dd> + + <p>Draws the given image onto the canvas. The arguments are + interpreted as follows:</p> + + <p><img alt="The sx and sy parameters give the x and y coordinates of the source rectangle; the sw and sh arguments give the width and height of the source rectangle; the dx and dy give the x and y coordinates of the destination rectangle; and the dw and dh arguments give the width and height of the destination rectangle." height="356" src="http://www.whatwg.org/specs/web-apps/current-work/http://images.whatwg.org/drawImage.png" width="356"/></p> + + <p>If the first argument isn't an <code><a href="#the-img-element">img</a></code>, + <code><a href="#the-canvas-element">canvas</a></code>, or <code><a href="#the-video-element">video</a></code> element, throws a + <code><a href="#type_mismatch_err">TYPE_MISMATCH_ERR</a></code> exception. If the image has no + image data, throws an <code><a href="#invalid_state_err">INVALID_STATE_ERR</a></code> exception. If + the one of the source rectangle dimensions is zero, throws an + <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception. If the image isn't yet + fully decoded, then nothing is drawn.</p> + + </dd> + + </dl><div class="impl"> + + <p>If not specified, the <var title="">dw</var> and <var title="">dh</var> arguments must default to the values of <var title="">sw</var> and <var title="">sh</var>, interpreted such that + one CSS pixel in the image is treated as one unit in the canvas + coordinate space. If the <var title="">sx</var>, <var title="">sy</var>, <var title="">sw</var>, and <var title="">sh</var> arguments are omitted, they must default to 0, 0, + the image's intrinsic width in image pixels, and the image's + intrinsic height in image pixels, respectively. If the image has no + intrinsic dimensions, the <i>concrete object size</i> must be used + instead, as determined using the CSS "<a href="http://dev.w3.org/csswg/css3-images/#default-sizing">Concrete + Object Size Resolution</a>" algorithm, with the <i>specified + size</i> having neither a definite width nor height, nor any + additional contraints, the object's intrinsic properties being those + of the <var title="">image</var> argument, and the <i>default object + size</i> being the size of the <code><a href="#the-canvas-element">canvas</a></code> element. <a href="#refsCSSIMAGES">[CSSIMAGES]</a></p> + + <p>The <var title="">image</var> argument is an instance of either + <code><a href="#htmlimageelement">HTMLImageElement</a></code>, <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code>, or + <code><a href="#htmlvideoelement">HTMLVideoElement</a></code>.</p> <!-- createPattern() has an + equivalent paragraph --> + + <p>If the <var title="">image</var> argument is an + <code><a href="#htmlimageelement">HTMLImageElement</a></code> object that is not <a href="#img-good" title="img-good">fully decodable</a>, or if the <var title="">image</var> argument is an <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> + object whose <code title="dom-media-readyState"><a href="#dom-media-readystate">readyState</a></code> + attribute is either <code title="dom-media-HAVE_NOTHING"><a href="#dom-media-have_nothing">HAVE_NOTHING</a></code> or <code title="dom-media-HAVE_METADATA"><a href="#dom-media-have_metadata">HAVE_METADATA</a></code>, then the + implementation must return without drawing anything.</p> <!-- + createPattern() has an equivalent paragraph --> + + <p>If the <var title="">image</var> argument is an + <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> object with either a horizontal + dimension or a vertical dimension equal to zero, then the + implementation must raise an <code><a href="#invalid_state_err">INVALID_STATE_ERR</a></code> + exception.</p> + <!-- createPattern() has an equivalent paragraph --> + + <p>The source rectangle is the rectangle whose corners are the four + points (<var title="">sx</var>, <var title="">sy</var>), (<span title=""><var title="">sx</var>+<var title="">sw</var></span>, <var title="">sy</var>), (<span title=""><var title="">sx</var>+<var title="">sw</var></span>, <span title=""><var title="">sy</var>+<var title="">sh</var></span>), (<var title="">sx</var>, <span title=""><var title="">sy</var>+<var title="">sh</var></span>).</p> + + <p>If one of the <var title="">sw</var> or <var title="">sh</var> + arguments is zero, the implementation must raise an + <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> exception.</p> + + <p>The destination rectangle is the rectangle whose corners are the + four points (<var title="">dx</var>, <var title="">dy</var>), + (<span title=""><var title="">dx</var>+<var title="">dw</var></span>, <var title="">dy</var>), (<span title=""><var title="">dx</var>+<var title="">dw</var></span>, <span title=""><var title="">dy</var>+<var title="">dh</var></span>), (<var title="">dx</var>, <span title=""><var title="">dy</var>+<var title="">dh</var></span>).</p> + + <p>When <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> is + invoked, the region of the image specified by the source rectangle + must be painted on the region of the canvas specified by the + destination rectangle, after applying the <a href="#transformations" title="dom-context-2d-transformation">current transformation + matrix</a> to the points of the destination rectangle.</p> + + <p>The original image data of the source image must be used, not the + image as it is rendered (e.g. <code title="attr-dim-width"><a href="#attr-dim-width">width</a></code> and <code title="attr-dim-height"><a href="#attr-dim-height">height</a></code> attributes on the source + element have no effect). The image data must be processed in the + original direction, even if the dimensions given are negative. <!-- + remove that last sentence if it causes confusion. Someone once + suggested that 5,5,-2,-2 was different than 3,3,2,2; this is trying + to clarify that this is no the case. --></p> + + <p class="note">This specification does not define the algorithm to + use when scaling the image, if necessary.</p> + + <p class="note">When a canvas is drawn onto itself, the <a href="#drawing-model">drawing + model</a> requires the source to be copied before the image is drawn + back onto the canvas, so it is possible to copy parts of a canvas + onto overlapping parts of itself.</p> + + <p>If the original image data is a bitmap image, the value painted + at a point in the destination rectangle is computed by filtering the + original image data. The user agent may use any filtering algorithm + (for example bilinear interpolation or nearest-neighbor). When the + filtering algorithm requires a pixel value from outside the original + image data, it must instead use the value from the nearest edge + pixel. (That is, the filter uses 'clamp-to-edge' behavior.)</p> + <!-- see CORE-32111 and: + http://krijnhoetmer.nl/irc-logs/whatwg/20100818#l-737 + http://www.w3.org/Bugs/Public/show_bug.cgi?id=10799#c11 + --> + <!-- createPattern() has a similar paragraph with different rules --> + + <p>When the <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method + is passed an animated image as its <var title="">image</var> + argument, the user agent must use the poster frame of the animation, + or, if there is no poster frame, the first frame of the + animation.</p> + <!-- createPattern() has an equivalent paragraph --> + + <p>When the <var title="">image</var> argument is an + <code><a href="#htmlvideoelement">HTMLVideoElement</a></code>, then the frame at the <a href="#current-playback-position">current + playback position</a> must be used as the source image, and the + source image's dimensions must be the <a href="#concept-video-intrinsic-width" title="concept-video-intrinsic-width">intrinsic width</a> and + <a href="#concept-video-intrinsic-height" title="concept-video-intrinsic-height">intrinsic height</a> + of the <a href="#media-resource">media resource</a> (i.e. after any aspect-ratio + correction has been applied).</p> + <!-- createPattern() has an equivalent paragraph --> + + <p>Images are painted without affecting the current path, and are + subject to <a href="#shadows" title="shadows">shadow effects</a>, <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, the <a href="#clipping-region" title="clipping region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operators</a>.</p> + + </div> + + + + <h6 id="pixel-manipulation"><span class="secno">4.8.11.1.11 </span><dfn>Pixel manipulation</dfn></h6> + + <dl class="domintro"><dt><var title="">imagedata</var> = <var title="">context</var> . <code title="dom-context-2d-createImageData"><a href="#dom-context-2d-createimagedata">createImageData</a></code>(<var title="">sw</var>, <var title="">sh</var>)</dt> + + <dd> + + <p>Returns an <code><a href="#imagedata">ImageData</a></code> object with the given + dimensions in CSS pixels (which might map to a different number of + actual device pixels exposed by the object itself). All the pixels + in the returned object are transparent black.</p> + + </dd> + + <dt><var title="">imagedata</var> = <var title="">context</var> . <code title="dom-context-2d-createImageData"><a href="#dom-context-2d-createimagedata">createImageData</a></code>(<var title="">imagedata</var>)</dt> + + <dd> + + <p>Returns an <code><a href="#imagedata">ImageData</a></code> object with the same + dimensions as the argument. All the pixels in the returned object + are transparent black.</p> + + </dd> + + <dt><var title="">imagedata</var> = <var title="">context</var> . <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData</a></code>(<var title="">sx</var>, <var title="">sy</var>, <var title="">sw</var>, <var title="">sh</var>)</dt> + + <dd> + + <p>Returns an <code><a href="#imagedata">ImageData</a></code> object containing the image + data for the given rectangle of the canvas.</p> + + <p>Throws a <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception if any of the + arguments are not finite. Throws an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> + exception if the either of the width or height arguments are + zero.</p> + + </dd> + + <dt><var title="">imagedata</var> . <code title="dom-imagedata-width"><a href="#dom-imagedata-width">width</a></code></dt> + <dt><var title="">imagedata</var> . <code title="dom-imagedata-height"><a href="#dom-imagedata-height">height</a></code></dt> + + <dd> + + <p>Returns the actual dimensions of the data in the <code><a href="#imagedata">ImageData</a></code> object, in device pixels.</p> + + </dd> + + <dt><var title="">imagedata</var> . <code title="dom-imagedata-data"><a href="#dom-imagedata-data">data</a></code></dt> + + <dd> + + <p>Returns the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.</p> + + </dd> + + <dt><var title="">context</var> . <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData</a></code>(<var title="">imagedata</var>, <var title="">dx</var>, <var title="">dy</var> [, <var title="">dirtyX</var>, <var title="">dirtyY</var>, <var title="">dirtyWidth</var>, <var title="">dirtyHeight</var> ])</dt> + + <dd> + + <p>Paints the data from the given <code><a href="#imagedata">ImageData</a></code> object + onto the canvas. If a dirty rectangle is provided, only the pixels + from that rectangle are painted.</p> + + <p>The <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code> + and <code title="dom-context-2d-globalCompositeOperation"><a href="#dom-context-2d-globalcompositeoperation">globalCompositeOperation</a></code> + attributes, as well as the shadow attributes, are ignored for the + purposes of this method call; pixels in the canvas are replaced + wholesale, with no composition, alpha blending, no shadows, + etc.</p> + + <p>If the first argument is null, throws a + <code><a href="#type_mismatch_err">TYPE_MISMATCH_ERR</a></code> exception. Throws a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception if any of the other + arguments are not finite.</p> + + </dd> + + </dl><div class="impl"> + + <p>The <dfn id="dom-context-2d-createimagedata" title="dom-context-2d-createImageData"><code>createImageData()</code></dfn> + method is used to instantiate new blank <code><a href="#imagedata">ImageData</a></code> + objects. When the method is invoked with two arguments <var title="">sw</var> and <var title="">sh</var>, it must return an + <code><a href="#imagedata">ImageData</a></code> object representing a rectangle with a width + in CSS pixels equal to the absolute magnitude of <var title="">sw</var> and a height in CSS pixels equal to the absolute + magnitude of <var title="">sh</var>. When invoked with a single <var title="">imagedata</var> argument, it must return an + <code><a href="#imagedata">ImageData</a></code> object representing a rectangle with the same + dimensions as the <code><a href="#imagedata">ImageData</a></code> object passed as the + argument. The <code><a href="#imagedata">ImageData</a></code> object returned must be filled + with transparent black.</p> + + <p>The <dfn id="dom-context-2d-getimagedata" title="dom-context-2d-getImageData"><code>getImageData(<var title="">sx</var>, <var title="">sy</var>, <var title="">sw</var>, + <var title="">sh</var>)</code></dfn> method must return an + <code><a href="#imagedata">ImageData</a></code> object representing the underlying pixel data + for the area of the canvas denoted by the rectangle whose corners are + the four points (<var title="">sx</var>, <var title="">sy</var>), + (<span title=""><var title="">sx</var>+<var title="">sw</var></span>, <var title="">sy</var>), (<span title=""><var title="">sx</var>+<var title="">sw</var></span>, <span title=""><var title="">sy</var>+<var title="">sh</var></span>), (<var title="">sx</var>, <span title=""><var title="">sy</var>+<var title="">sh</var></span>), in canvas + coordinate space units. Pixels outside the canvas must be returned + as transparent black. Pixels must be returned as non-premultiplied + alpha values.</p> + + <p>If any of the arguments to <code title="dom-context-2d-createImageData"><a href="#dom-context-2d-createimagedata">createImageData()</a></code> or + <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> + are infinite or NaN, the method must instead raise a + <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception. If either the <var title="">sw</var> or <var title="">sh</var> arguments are zero, + the method must instead raise an <code><a href="#index_size_err">INDEX_SIZE_ERR</a></code> + exception.</p> + + <p><code><a href="#imagedata">ImageData</a></code> objects must be initialized so that their + <dfn id="dom-imagedata-width" title="dom-imagedata-width"><code>width</code></dfn> attribute + is set to <var title="">w</var>, the number of physical device + pixels per row in the image data, their <dfn id="dom-imagedata-height" title="dom-imagedata-height"><code>height</code></dfn> attribute is + set to <var title="">h</var>, the number of rows in the image data, + and their <dfn id="dom-imagedata-data" title="dom-imagedata-data"><code>data</code></dfn> + attribute is initialized to a <code><a href="#canvaspixelarray">CanvasPixelArray</a></code> object + holding the image data. At least one pixel's worth of image data + must be returned.</p> + + <p>The <code><a href="#canvaspixelarray">CanvasPixelArray</a></code> object provides ordered, + indexed access to the color components of each pixel of the image + data. The data must be represented in left-to-right order, row by + row top to bottom, starting with the top left, with each pixel's + red, green, blue, and alpha components being given in that order for + each pixel. Each component of each device pixel represented in this + array must be in the range 0..255, representing the 8 bit value for + that component. The components must be assigned consecutive indices + starting with 0 for the top left pixel's red component.</p> + + <p>The <code><a href="#canvaspixelarray">CanvasPixelArray</a></code> object thus represents <var title="">h</var>×<var title="">w</var>×4 integers. The + <dfn id="dom-canvaspixelarray-length" title="dom-canvaspixelarray-length"><code>length</code></dfn> + attribute of a <code><a href="#canvaspixelarray">CanvasPixelArray</a></code> object must return this + number.</p> + + <p>The object's <a href="#supported-property-indices">supported property indices</a> are the + numbers in the range 0 .. <span title=""><var title="">h</var>×<var title="">w</var>×4-1</span>.</p> + + <p>To <dfn id="dom-canvaspixelarray-get" title="dom-CanvasPixelArray-get">determine the value of + an indexed property</dfn> <var title="">index</var>, the user agent + must return the value of the <var title="">index</var>th component + in the array.</p> + + <p>To <dfn id="dom-canvaspixelarray-set" title="dom-CanvasPixelArray-set">set the value of an + existing indexed property</dfn> <var title="">index</var> to value + <var title="">value</var>, the value of the <var title="">index</var>th component in the array must be set to <var title="">value</var>.</p> + + <p class="note">The width and height (<var title="">w</var> and <var title="">h</var>) might be different from the <var title="">sw</var> + and <var title="">sh</var> arguments to the above methods, e.g. if + the canvas is backed by a high-resolution bitmap, or if the <var title="">sw</var> and <var title="">sh</var> arguments are + negative.</p> + + <p>The <dfn id="dom-context-2d-putimagedata" title="dom-context-2d-putImageData"><code>putImageData(<var title="">imagedata</var>, <var title="">dx</var>, <var title="">dy</var>, <var title="">dirtyX</var>, <var title="">dirtyY</var>, <var title="">dirtyWidth</var>, <var title="">dirtyHeight</var>)</code></dfn> method writes data from + <code><a href="#imagedata">ImageData</a></code> structures back to the canvas.</p> + + <p>If any of the arguments to the method are infinite or NaN, the + method must raise a <code><a href="#not_supported_err">NOT_SUPPORTED_ERR</a></code> exception.</p> + + <p>When the last four arguments are omitted, they must be assumed to + have the values 0, 0, the <code title="dom-imagedata-width"><a href="#dom-imagedata-width">width</a></code> member of the <var title="">imagedata</var> structure, and the <code title="dom-imagedata-height"><a href="#dom-imagedata-height">height</a></code> member of the <var title="">imagedata</var> structure, respectively.</p> + + <p>When invoked with arguments that do not, per the last few + paragraphs, cause an exception to be raised, the <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData()</a></code> method + must act as follows:</p> + + <ol><li> + + <p>Let <var title="">dx<sub>device</sub></var> be the x-coordinate + of the device pixel in the underlying pixel data of the canvas + corresponding to the <var title="">dx</var> coordinate in the + canvas coordinate space.</p> + + <p>Let <var title="">dy<sub>device</sub></var> be the y-coordinate + of the device pixel in the underlying pixel data of the canvas + corresponding to the <var title="">dy</var> coordinate in the + canvas coordinate space.</p> + + </li> + + <li> + + <p>If <var title="">dirtyWidth</var> is negative, let <var title="">dirtyX</var> be <span title=""><var title="">dirtyX</var>+<var title="">dirtyWidth</var></span>, and let <var title="">dirtyWidth</var> be equal to the absolute magnitude of + <var title="">dirtyWidth</var>.</p> + + <p>If <var title="">dirtyHeight</var> is negative, let <var title="">dirtyY</var> be <span title=""><var title="">dirtyY</var>+<var title="">dirtyHeight</var></span>, and let <var title="">dirtyHeight</var> be equal to the absolute magnitude of + <var title="">dirtyHeight</var>.</p> + + </li> + + <li> + + <p>If <var title="">dirtyX</var> is negative, let <var title="">dirtyWidth</var> be <span title=""><var title="">dirtyWidth</var>+<var title="">dirtyX</var></span>, and + let <var title="">dirtyX</var> be zero.</p> + + <p>If <var title="">dirtyY</var> is negative, let <var title="">dirtyHeight</var> be <span title=""><var title="">dirtyHeight</var>+<var title="">dirtyY</var></span>, and + let <var title="">dirtyY</var> be zero.</p> + + </li> + + <li> + + <p>If <span title=""><var title="">dirtyX</var>+<var title="">dirtyWidth</var></span> is greater than the <code title="dom-imagedata-width"><a href="#dom-imagedata-width">width</a></code> attribute of the <var title="">imagedata</var> argument, let <var title="">dirtyWidth</var> be the value of that <code title="dom-imagedata-width"><a href="#dom-imagedata-width">width</a></code> attribute, minus the + value of <var title="">dirtyX</var>.</p> + + <p>If <span title=""><var title="">dirtyY</var>+<var title="">dirtyHeight</var></span> is greater than the <code title="dom-imagedata-height"><a href="#dom-imagedata-height">height</a></code> attribute of the <var title="">imagedata</var> argument, let <var title="">dirtyHeight</var> be the value of that <code title="dom-imagedata-height"><a href="#dom-imagedata-height">height</a></code> attribute, minus the + value of <var title="">dirtyY</var>.</p> + + </li> + + <li> + + <p>If, after those changes, either <var title="">dirtyWidth</var> + or <var title="">dirtyHeight</var> is negative or zero, stop these + steps without affecting the canvas.</p> + + </li> + + <li><p>Otherwise, for all integer values of <var title="">x</var> + and <var title="">y</var> where <span title=""><var title="">dirtyX</var> ≤ <var title="">x</var> < <span title=""><var title="">dirtyX</var>+<var title="">dirtyWidth</var></span></span> + and <span title=""><var title="">dirtyY</var> ≤ <var title="">y</var> < <span title=""><var title="">dirtyY</var>+<var title="">dirtyHeight</var></span></span>, copy the four channels of + the pixel with coordinate (<var title="">x</var>, <var title="">y</var>) in the <var title="">imagedata</var> data + structure to the pixel with coordinate (<span title=""><var title="">dx<sub>device</sub></var>+<var title="">x</var></span>, + <span title=""><var title="">dy<sub>device</sub></var>+<var title="">y</var></span>) in the underlying pixel data of the + canvas.</p></li> + + </ol><p>The handling of pixel rounding when the specified coordinates do + not exactly map to the device coordinate space is not defined by + this specification, except that the following must result in no + visible changes to the rendering:</p> + + <pre>context.putImageData(context.getImageData(x, y, w, h), p, q);</pre> + + <p>...for any value of <var title="">x</var>, <var title="">y</var>, + <var title="">w</var>, and <var title="">h</var> and where <var title="">p</var> is the smaller of <var title="">x</var> and the sum + of <var title="">x</var> and <var title="">w</var>, and <var title="">q</var> is the smaller of <var title="">y</var> and the sum + of <var title="">y</var> and <var title="">h</var>; and except that + the following two calls:</p> + + <pre>context.createImageData(w, h); +context.getImageData(0, 0, w, h);</pre> + + <p>...must return <code><a href="#imagedata">ImageData</a></code> objects with the same + dimensions, for any value of <var title="">w</var> and <var title="">h</var>. In other words, while user agents may round the + arguments of these methods so that they map to device pixel + boundaries, any rounding performed must be performed consistently + for all of the <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">createImageData()</a></code>, <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> and <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData()</a></code> + operations.</p> + + <p class="note">Due to the lossy nature of converting to and from + premultiplied alpha color values, pixels that have just been set + using <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData()</a></code> might be + returned to an equivalent <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> as + different values.</p> + + <p>The current path, <a href="#transformations" title="dom-context-2d-transformation">transformation matrix</a>, + <a href="#shadows" title="shadows">shadow attributes</a>, <a href="#dom-context-2d-globalalpha" title="dom-context-2d-globalAlpha">global alpha</a>, the <a href="#clipping-region" title="clipping region">clipping region</a>, and <a href="#dom-context-2d-globalcompositeoperation" title="dom-context-2d-globalCompositeOperation">global composition + operator</a> must not affect the <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> and <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData()</a></code> + methods.</p> + + </div> + + <div class="example"> + + <p>The data returned by <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> is at the + resolution of the canvas backing store, which is likely to not be + one device pixel to each CSS pixel if the display used is a high + resolution display.</p> + + <p>In the following example, the script generates an + <code><a href="#imagedata">ImageData</a></code> object so that it can draw onto it.</p> + + <pre>// canvas is a reference to a <canvas> element +var context = canvas.getContext('2d'); + +// create a blank slate +var data = context.createImageData(canvas.width, canvas.height); + +// create some plasma +FillPlasma(data, 'green'); // green plasma + +// add a cloud to the plasma +AddCloud(data, data.width/2, data.height/2); // put a cloud in the middle + +// paint the plasma+cloud on the canvas +context.putImageData(data, 0, 0); + +// support methods +function FillPlasma(data, color) { ... } +function AddCloud(data, x, y) { ... }</pre> + + </div> + + <div class="example"> + + <p>Here is an example of using <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> and <code title="dom-context-2d-putImageData"><a href="#dom-context-2d-putimagedata">putImageData()</a></code> to + implement an edge detection filter.</p> + + <pre><!DOCTYPE HTML> +<html> + <head> + <title>Edge detection demo</title> + <script> + var image = new Image(); + function init() { + image.onload = demo; + image.src = "image.jpeg"; + } + function demo() { + var canvas = document.getElementsByTagName('canvas')[0]; + var context = canvas.getContext('2d'); + + // draw the image onto the canvas + context.drawImage(image, 0, 0); + + // get the image data to manipulate + var input = context.getImageData(0, 0, canvas.width, canvas.height); + + // get an empty slate to put the data into + var output = context.createImageData(canvas.width, canvas.height); + + // alias some variables for convenience + // notice that we are using input.width and input.height here + // as they might not be the same as canvas.width and canvas.height + // (in particular, they might be different on high-res displays) + var w = input.width, h = input.height; + var inputData = input.data; + var outputData = output.data; + + // edge detection + for (var y = 1; y < h-1; y += 1) { + for (var x = 1; x < w-1; x += 1) { + for (var c = 0; c < 3; c += 1) { + var i = (y*w + x)*4 + c; + outputData[i] = 127 + -inputData[i - w*4 - 4] - inputData[i - w*4] - inputData[i - w*4 + 4] + + -inputData[i - 4] + 8*inputData[i] - inputData[i + 4] + + -inputData[i + w*4 - 4] - inputData[i + w*4] - inputData[i + w*4 + 4]; + } + outputData[(y*w + x)*4 + 3] = 255; // alpha + } + } + + // put the image data back after manipulation + context.putImageData(output, 0, 0); + } + </script> + </head> + <body onload="init()"> + <canvas></canvas> + </body> +</html></pre> + + </div> + + + <div class="impl"> + + <h6 id="drawing-model"><span class="secno">4.8.11.1.12 </span><dfn>Drawing model</dfn></h6> + + <p>When a shape or image is painted, user agents must follow these + steps, in the order given (or act as if they do):</p> + + <ol><li><p>Render the shape or image onto an infinite transparent black + bitmap, creating image <var title="">A</var>, as described in the + previous sections. For shapes, the current fill, stroke, and line + styles must be honored, and the stroke must itself also be + subjected to the current transformation matrix.</p></li> + + <li><p><a href="#when-shadows-are-drawn">When shadows are drawn</a>, render the shadow from + image <var title="">A</var>, using the current shadow styles, + creating image <var title="">B</var>.</p></li> + + <li><p><a href="#when-shadows-are-drawn">When shadows are drawn</a>, multiply the alpha + component of every pixel in <var title="">B</var> by <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code>.</p></li> + + <li><p><a href="#when-shadows-are-drawn">When shadows are drawn</a>, composite <var title="">B</var> within the <a href="#clipping-region">clipping region</a> over the + current canvas bitmap using the current composition + operator.</p></li> + + <li><p>Multiply the alpha component of every pixel in <var title="">A</var> by <code title="dom-context-2d-globalAlpha"><a href="#dom-context-2d-globalalpha">globalAlpha</a></code>.</p></li> + + <li><p>Composite <var title="">A</var> within the <a href="#clipping-region">clipping + region</a> over the current canvas bitmap using the current + composition operator.</p></li> + + </ol></div> + + + <h6 id="best-practices"><span class="secno">4.8.11.1.13 </span>Best practices</h6> + + <p><i>This section is non-normative.</i></p> + + <p>When a canvas is interactive, authors should include focusable + elements in the element's fallback content corresponding to each + focusable part of the canvas, as in the <a href="#drawCustomFocusRingExample">example above</a>.</p> + + <p>To indicate which focusable part of the canvas is currently + focused, authors should use the <code title="dom-context-2d-drawSystemFocusRing"><a href="#dom-context-2d-drawsystemfocusring">drawSystemFocusRing()</a></code> + method, passing it the element for which a ring is being drawn. This + method only draws the focus ring if the element is focused, so that + it can simply be called whenever drawing the element, without + checking whether the element is focused or not first.</p> + + <p>Authors should avoid implementing text editing controls using the + <code><a href="#the-canvas-element">canvas</a></code> element. Doing so has a large number of + disadvantages:</p> + + <ul><li>Mouse placement of the caret has to be reimplemented.</li> + + <li>Keyboard movement of the caret has to be reimplemented (possibly across lines, for multiline text input).</li> + + <li>Scrolling of the text field has to be implemented (horizontally for long lines, vertically for multiline input).</li> + + <li>Native features such as copy-and-paste have to be reimplemented.</li> + + <li>Native features such as spell-checking have to be reimplemented.</li> + + <li>Native features such as drag-and-drop have to be reimplemented.</li> + + <li>Native features such as page-wide text search have to be reimplemented.</li> + + <li>Native features specific to the user, for example custom text + services, have to be reimplemented. This is close to impossible + since each user might have different services installed, and there + is an unbounded set of possible such services.</li> + + <li>Bidirectional text editing has to be reimplemented.</li> + + <li>For multiline text editing, line wrapping has to be implemented for all relevant languages.</li> + + <li>Text selection has to be reimplemented.</li> + + <li>Dragging of bidirectional text selections has to be reimplemented.</li> + + <li>Platform-native keyboard shortcuts have to be reimplemented.</li> + + <li>Platform-native input method editors (IMEs) have to be reimplemented.</li> + + <li>Undo and redo functionality has to be reimplemented.</li> + + <li>Accessibility features such as magnification following the + caret or selection have to be reimplemented.</li> + + </ul><p>This is a huge amount of work, and authors are most strongly + encouraged to avoid doing any of it by instead using the + <code><a href="#the-input-element">input</a></code> element, the <code><a href="#the-textarea-element">textarea</a></code> element, or + the <code title="attr-contenteditable"><a href="#attr-contenteditable">contenteditable</a></code> + attribute.</p> + + + <h6 id="examples"><span class="secno">4.8.11.1.14 </span>Examples</h6> + + <p><i>This section is non-normative.</i></p> + + <div class="example"> + + <p>Here is an example of a script that uses canvas to draw <a href="data:text/html;charset=utf-8;base64,PCFET0NUWVBFIEhUTUw%2BDQo8aHRtbCBsYW5nPSJlbiI%2BDQogPGhlYWQ%2BDQogIDx0aXRsZT5QcmV0dHkgR2xvd2luZyBMaW5lczwvdGl0bGU%2BDQogPC9oZWFkPg0KIDxib2R5Pg0KPGNhbnZhcyB3aWR0aD0iODAwIiBoZWlnaHQ9IjQ1MCI%2BPC9jYW52YXM%2BDQo8c2NyaXB0Pg0KDQogdmFyIGNvbnRleHQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnY2FudmFzJylbMF0uZ2V0Q29udGV4dCgnMmQnKTsNCg0KIHZhciBsYXN0WCA9IGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKTsNCiB2YXIgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KIHZhciBodWUgPSAwOw0KIGZ1bmN0aW9uIGxpbmUoKSB7DQogICBjb250ZXh0LnNhdmUoKTsNCiAgIGNvbnRleHQudHJhbnNsYXRlKGNvbnRleHQuY2FudmFzLndpZHRoLzIsIGNvbnRleHQuY2FudmFzLmhlaWdodC8yKTsNCiAgIGNvbnRleHQuc2NhbGUoMC45LCAwLjkpOw0KICAgY29udGV4dC50cmFuc2xhdGUoLWNvbnRleHQuY2FudmFzLndpZHRoLzIsIC1jb250ZXh0LmNhbnZhcy5oZWlnaHQvMik7DQogICBjb250ZXh0LmJlZ2luUGF0aCgpOw0KICAgY29udGV4dC5saW5lV2lkdGggPSA1ICsgTWF0aC5yYW5kb20oKSAqIDEwOw0KICAgY29udGV4dC5tb3ZlVG8obGFzdFgsIGxhc3RZKTsNCiAgIGxhc3RYID0gY29udGV4dC5jYW52YXMud2lkdGggKiBNYXRoLnJhbmRvbSgpOw0KICAgbGFzdFkgPSBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpOw0KICAgY29udGV4dC5iZXppZXJDdXJ2ZVRvKGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuY2FudmFzLndpZHRoICogTWF0aC5yYW5kb20oKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgKiBNYXRoLnJhbmRvbSgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RYLCBsYXN0WSk7DQoNCiAgIGh1ZSA9IGh1ZSArIDEwICogTWF0aC5yYW5kb20oKTsNCiAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSAnaHNsKCcgKyBodWUgKyAnLCA1MCUsIDUwJSknOw0KICAgY29udGV4dC5zaGFkb3dDb2xvciA9ICd3aGl0ZSc7DQogICBjb250ZXh0LnNoYWRvd0JsdXIgPSAxMDsNCiAgIGNvbnRleHQuc3Ryb2tlKCk7DQogICBjb250ZXh0LnJlc3RvcmUoKTsNCiB9DQogc2V0SW50ZXJ2YWwobGluZSwgNTApOw0KDQogZnVuY3Rpb24gYmxhbmsoKSB7DQogICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDAsMCwwLDAuMSknOw0KICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCBjb250ZXh0LmNhbnZhcy53aWR0aCwgY29udGV4dC5jYW52YXMuaGVpZ2h0KTsNCiB9DQogc2V0SW50ZXJ2YWwoYmxhbmssIDQwKTsNCg0KPC9zY3JpcHQ%2BDQogPC9ib2R5Pg0KPC9odG1sPg0K">pretty glowing lines</a>.</p> + + <pre><canvas width="800" height="450"></canvas> +<script> + + var context = document.getElementsByTagName('canvas')[0].getContext('2d'); + + var lastX = context.canvas.width * Math.random(); + var lastY = context.canvas.height * Math.random(); + var hue = 0; + function line() { + context.save(); + context.translate(context.canvas.width/2, context.canvas.height/2); + context.scale(0.9, 0.9); + context.translate(-context.canvas.width/2, -context.canvas.height/2); + context.beginPath(); + context.lineWidth = 5 + Math.random() * 10; + context.moveTo(lastX, lastY); + lastX = context.canvas.width * Math.random(); + lastY = context.canvas.height * Math.random(); + context.bezierCurveTo(context.canvas.width * Math.random(), + context.canvas.height * Math.random(), + context.canvas.width * Math.random(), + context.canvas.height * Math.random(), + lastX, lastY); + + hue = hue + 10 * Math.random(); + context.strokeStyle = 'hsl(' + hue + ', 50%, 50%)'; + context.shadowColor = 'white'; + context.shadowBlur = 10; + context.stroke(); + context.restore(); + } + setInterval(line, 50); + + function blank() { + context.fillStyle = 'rgba(0,0,0,0.1)'; + context.fillRect(0, 0, context.canvas.width, context.canvas.height); + } + setInterval(blank, 40); + +</script></pre> + + </div> + + + + </div><!--data-component--> + + <!--2DCONTEXT--> + + <div class="impl"> + + <h5 id="color-spaces-and-color-correction"><span class="secno">4.8.11.2 </span>Color spaces and color correction</h5> + + <p>The <code><a href="#the-canvas-element">canvas</a></code> APIs must perform color correction at + only two points: when rendering images with their own gamma + correction and color space information onto the canvas, to convert + the image to the color space used by the canvas (e.g. using the 2D + Context's <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> + method with an <code><a href="#htmlimageelement">HTMLImageElement</a></code> object), and when + rendering the actual canvas bitmap to the output device.</p> + + <p class="note">Thus, in the 2D context, colors used to draw shapes + onto the canvas will exactly match colors obtained through the <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> + method.</p> + + <p>The <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL()</a></code> method + must not include color space information in the resource + returned. Where the output format allows it, the color of pixels in + resources created by <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL()</a></code> must match those + returned by the <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> + method.</p> + + <p>In user agents that support CSS, the color space used by a + <code><a href="#the-canvas-element">canvas</a></code> element must match the color space used for + processing any colors for that element in CSS.</p> + + <p>The gamma correction and color space information of images must + be handled in such a way that an image rendered directly using an + <code><a href="#the-img-element">img</a></code> element would use the same colors as one painted on + a <code><a href="#the-canvas-element">canvas</a></code> element that is then itself + rendered. Furthermore, the rendering of images that have no color + correction information (such as those returned by the <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL()</a></code> method) must be + rendered with no color correction.</p> + + <p class="note">Thus, in the 2D context, calling the <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method to render + the output of the <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL()</a></code> method to the + canvas, given the appropriate dimensions, has no visible effect.</p> + + </div> + + + <div class="impl"> + + <h5 id="security-with-canvas-elements"><span class="secno">4.8.11.3 </span>Security with <code><a href="#the-canvas-element">canvas</a></code> elements</h5> + + <p><strong>Information leakage</strong> can occur if scripts from + one <a href="#origin">origin</a> can access information (e.g. read pixels) + from images from another origin (one that isn't the <a href="#same-origin" title="same origin">same</a>).</p> + + <p>To mitigate this, <code><a href="#the-canvas-element">canvas</a></code> elements are defined to + have a flag indicating whether they are <i>origin-clean</i>. All + <code><a href="#the-canvas-element">canvas</a></code> elements must start with their + <i>origin-clean</i> set to true. The flag must be set to false if + any of the following actions occur:</p> + + <ul><li><p>The element's 2D context's <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method is + called with an <code><a href="#htmlimageelement">HTMLImageElement</a></code> or an + <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> whose <a href="#origin">origin</a> is not the + <a href="#same-origin" title="same origin">same</a> as that of the + <code><a href="#document">Document</a></code> object that owns the <code><a href="#the-canvas-element">canvas</a></code> + element.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-drawImage"><a href="#dom-context-2d-drawimage">drawImage()</a></code> method is + called with an <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> whose + <i>origin-clean</i> flag is false.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> attribute is set + to a <code><a href="#canvaspattern">CanvasPattern</a></code> object that was created from an + <code><a href="#htmlimageelement">HTMLImageElement</a></code> or an <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> + whose <a href="#origin">origin</a> was not the <a href="#same-origin" title="same + origin">same</a> as that of the <code><a href="#document">Document</a></code> object + that owns the <code><a href="#the-canvas-element">canvas</a></code> element when the pattern was + created.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-fillStyle"><a href="#dom-context-2d-fillstyle">fillStyle</a></code> attribute is set + to a <code><a href="#canvaspattern">CanvasPattern</a></code> object that was created from an + <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> whose <i>origin-clean</i> flag was + false when the pattern was created.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> attribute is + set to a <code><a href="#canvaspattern">CanvasPattern</a></code> object that was created from an + <code><a href="#htmlimageelement">HTMLImageElement</a></code> or an <code><a href="#htmlvideoelement">HTMLVideoElement</a></code> + whose <a href="#origin">origin</a> was not the <a href="#same-origin" title="same + origin">same</a> as that of the <code><a href="#document">Document</a></code> object + that owns the <code><a href="#the-canvas-element">canvas</a></code> element when the pattern was + created.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-strokeStyle"><a href="#dom-context-2d-strokestyle">strokeStyle</a></code> attribute is + set to a <code><a href="#canvaspattern">CanvasPattern</a></code> object that was created from an + <code><a href="#htmlcanvaselement">HTMLCanvasElement</a></code> whose <i>origin-clean</i> flag was + false when the pattern was created.</p></li> + + <li><p>The element's 2D context's <code title="dom-context-2d-fillText"><a href="#dom-context-2d-filltext">fillText()</a></code> or <code title="dom-context-2d-fillText"><a href="#dom-context-2d-filltext">strokeText()</a></code> methods are + invoked and consider using a font that has an <a href="#origin">origin</a> + that is not the <a href="#same-origin" title="same origin">same</a> as that of + the <code><a href="#document">Document</a></code> object that owns the <code><a href="#the-canvas-element">canvas</a></code> + element. (The font doesn't even have to be used; all that matters + is whether the font was considered for any of the glyphs + drawn.)</p></li> <!-- because fonts could consider sensitive + material, I guess; and because that sensitivity could extend to + whether or not a particular glyph is in the font in the first + place. --> + + </ul><p>Whenever the <code title="dom-canvas-toDataURL"><a href="#dom-canvas-todataurl">toDataURL()</a></code> method of a + <code><a href="#the-canvas-element">canvas</a></code> element whose <i>origin-clean</i> flag is set to + false is called, the method must raise a <code><a href="#security_err">SECURITY_ERR</a></code> + exception.</p> + + <p>Whenever the <code title="dom-context-2d-getImageData"><a href="#dom-context-2d-getimagedata">getImageData()</a></code> method of + the 2D context of a <code><a href="#the-canvas-element">canvas</a></code> element whose + <i>origin-clean</i> flag is set to false is called with otherwise + correct arguments, the method must raise a <code><a href="#security_err">SECURITY_ERR</a></code> + exception.</p> + + <p>Whenever the <code title="dom-context-2d-measureText"><a href="#dom-context-2d-measuretext">measureText()</a></code> method of + the 2D context of a <code><a href="#the-canvas-element">canvas</a></code> element ends up using a font + that has an <a href="#origin">origin</a> that is not the <a href="#same-origin" title="same + origin">same</a> as that of the <code><a href="#document">Document</a></code> object that + owns the <code><a href="#the-canvas-element">canvas</a></code> element, the method must raise a + <code><a href="#security_err">SECURITY_ERR</a></code> exception.</p> + + <p class="note">Even resetting the canvas state by changing its + <code title="attr-canvas-width"><a href="#attr-canvas-width">width</a></code> or <code title="attr-canvas-height"><a href="#attr-canvas-height">height</a></code> attributes doesn't reset + the <i>origin-clean</i> flag.</p> + + </div> + + + + </body></html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentest.py b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentest.py new file mode 100644 index 0000000..c15f242 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentest.py
@@ -0,0 +1,3 @@ +from gentestutils import genTestUtils + +genTestUtils('../../2dcontext', '../../2dcontext', 'templates.yaml', 'name2dir.yaml', False)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentestutils.py b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentestutils.py new file mode 100644 index 0000000..fb7bf18 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/gentestutils.py
@@ -0,0 +1,813 @@ +# Copyright (c) 2010 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +# Current code status: +# +# This was originally written for use at +# http://philip.html5.org/tests/canvas/suite/tests/ +# +# It has been adapted for use with the Web Platform Test Suite suite at +# https://github.com/w3c/web-platform-tests/ +# +# The W3C version excludes a number of features (multiple versions of each test +# case of varying verbosity, Mozilla mochitests, semi-automated test harness) +# to focus on simply providing reviewable test cases. It also expects a different +# directory structure. +# This code attempts to support both versions, but the non-W3C version hasn't +# been tested recently and is probably broken. + +# To update or add test cases: +# +# * Modify the tests*.yaml files. +# 'name' is an arbitrary hierarchical name to help categorise tests. +# 'desc' is a rough description of what behaviour the test aims to test. +# 'testing' is a list of references to spec.yaml, to show which spec sentences +# this test case is primarily testing. +# 'code' is JavaScript code to execute, with some special commands starting with '@' +# 'expected' is what the final canvas output should be: a string 'green' or 'clear' +# (100x50 images in both cases), or a string 'size 100 50' (or any other size) +# followed by Python code using Pycairo to generate the image. +# +# * Run "python gentest.py". +# This requires a few Python modules which might not be ubiquitous. +# It has only been tested on Linux. +# It will usually emit some warnings, which ideally should be fixed but can +# generally be safely ignored. +# +# * Test the tests, add new ones to Git, remove deleted ones from Git, etc. + +import re +import codecs +import time +import os +import shutil +import sys +import xml.dom.minidom +from xml.dom.minidom import Node + +try: + import cairocffi as cairo +except ImportError: + import cairo + +try: + import syck as yaml # compatible and lots faster +except ImportError: + import yaml + +def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOFFSCREENCANVAS): + + # Default mode is for the W3C test suite; the --standalone option + # generates various extra files that aren't needed there + W3CMODE = True + if '--standalone' in sys.argv: + W3CMODE = False + + MISCOUTPUTDIR = './output' + SPECOUTPUTDIR = '../../annotated-spec' + + SPECOUTPUTPATH = '../annotated-spec' # relative to TESTOUTPUTDIR + + def simpleEscapeJS(str): + return str.replace('\\', '\\\\').replace('"', '\\"') + + def escapeJS(str): + str = simpleEscapeJS(str) + str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output + return str + + def escapeHTML(str): + return str.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"') + + def expand_nonfinite(method, argstr, tail): + """ + >>> print expand_nonfinite('f', '<0 a>, <0 b>', ';') + f(a, 0); + f(0, b); + f(a, b); + >>> print expand_nonfinite('f', '<0 a>, <0 b c>, <0 d>', ';') + f(a, 0, 0); + f(0, b, 0); + f(0, c, 0); + f(0, 0, d); + f(a, b, 0); + f(a, b, d); + f(a, 0, d); + f(0, b, d); + """ + # argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually + # 'invalid' is Infinity/-Infinity/NaN) + args = [] + for arg in argstr.split(', '): + a = re.match('<(.*)>', arg).group(1) + args.append(a.split(' ')) + calls = [] + # Start with the valid argument list + call = [ args[j][0] for j in range(len(args)) ] + # For each argument alone, try setting it to all its invalid values: + for i in range(len(args)): + for a in args[i][1:]: + c2 = call[:] + c2[i] = a + calls.append(c2) + # For all combinations of >= 2 arguments, try setting them to their + # first invalid values. (Don't do all invalid values, because the + # number of combinations explodes.) + def f(c, start, depth): + for i in range(start, len(args)): + if len(args[i]) > 1: + a = args[i][1] + c2 = c[:] + c2[i] = a + if depth > 0: calls.append(c2) + f(c2, i+1, depth+1) + f(call, 0, 0) + + return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls) + + # Run with --test argument to run unit tests + if len(sys.argv) > 1 and sys.argv[1] == '--test': + import doctest + doctest.testmod() + sys.exit() + + templates = yaml.load(open(TEMPLATEFILE, "r").read()) + name_mapping = yaml.load(open(NAME2DIRFILE, "r").read()) + + SPECFILE = 'spec.yaml' + if ISOFFSCREENCANVAS: + SPECFILE = '../../2dcontext/tools/spec.yaml' + spec_assertions = [] + for s in yaml.load(open(SPECFILE, "r").read())['assertions']: + if 'meta' in s: + eval(compile(s['meta'], '<meta spec assertion>', 'exec'), {}, {'assertions':spec_assertions}) + else: + spec_assertions.append(s) + + tests = [] + TESTSFILES = ['tests.yaml', 'tests2d.yaml', 'tests2dtext.yaml'] + if ISOFFSCREENCANVAS: + TESTSFILES = ['tests2d.yaml'] + for t in sum([ yaml.load(open(f, "r").read()) for f in TESTSFILES], []): + if 'DISABLED' in t: + continue + if 'meta' in t: + eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests}) + else: + tests.append(t) + + category_names = [] + category_contents_direct = {} + category_contents_all = {} + + spec_ids = {} + for t in spec_assertions: spec_ids[t['id']] = True + spec_refs = {} + + def backref_html(name): + backrefs = [] + c = '' + for p in name.split('.')[:-1]: + c += '.'+p + backrefs.append('<a href="index%s.html">%s</a>.' % (c, p)) + backrefs.append(name.split('.')[-1]) + return ''.join(backrefs) + + def make_flat_image(filename, w, h, r,g,b,a): + if os.path.exists('%s/%s' % (IMAGEOUTPUTDIR, filename)): + return filename + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h) + cr = cairo.Context(surface) + cr.set_source_rgba(r, g, b, a) + cr.rectangle(0, 0, w, h) + cr.fill() + surface.write_to_png('%s/%s' % (IMAGEOUTPUTDIR, filename)) + return filename + + # Ensure the test output directories exist + testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR] + if not W3CMODE: testdirs.append('%s/mochitests' % MISCOUTPUTDIR) + else: + for map_dir in set(name_mapping.values()): + testdirs.append("%s/%s" % (TESTOUTPUTDIR, map_dir)) + for d in testdirs: + try: os.mkdir(d) + except: pass # ignore if it already exists + + mochitests = [] + used_images = {} + + def expand_test_code(code): + code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws' + + if ISOFFSCREENCANVAS: + code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);', + r'_assertPixel(offscreenCanvas, \1, \2, "\1", "\2");', + code) + else: + code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);', + r'_assertPixel(canvas, \1, \2, "\1", "\2");', + code) + + if ISOFFSCREENCANVAS: + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);', + r'_assertPixelApprox(offscreenCanvas, \1, \2, "\1", "\2", 2);', + code) + else: + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);', + r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", 2);', + code) + + if ISOFFSCREENCANVAS: + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', + r'_assertPixelApprox(offscreenCanvas, \1, \2, "\1", "\2", \3);', + code) + else: + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', + r'_assertPixelApprox(canvas, \1, \2, "\1", "\2", \3);', + code) + + code = re.sub(r'@assert throws (\S+_ERR) (.*);', + r'assert_throws("\1", function() { \2; });', + code) + + code = re.sub(r'@assert throws (\S+Error) (.*);', + r'assert_throws(new \1(), function() { \2; });', + code) + + code = re.sub(r'@assert (.*) === (.*);', + lambda m: '_assertSame(%s, %s, "%s", "%s");' + % (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) + , code) + + code = re.sub(r'@assert (.*) !== (.*);', + lambda m: '_assertDifferent(%s, %s, "%s", "%s");' + % (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) + , code) + + code = re.sub(r'@assert (.*) =~ (.*);', + lambda m: 'assert_regexp_match(%s, %s);' + % (m.group(1), m.group(2)) + , code) + + code = re.sub(r'@assert (.*);', + lambda m: '_assert(%s, "%s");' + % (m.group(1), escapeJS(m.group(1))) + , code) + + code = re.sub(r' @moz-todo', '', code) + + code = re.sub(r'@moz-UniversalBrowserRead;', + "" + , code) + + assert('@' not in code) + + return code + + def expand_mochitest_code(code): + code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) + + code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);', + r'isPixel(ctx, \1, \2, "\1", "\2", 0);', + code) + + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);', + r'isPixel(ctx, \1, \2, "\1", "\2", 2);', + code) + + code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', + r'isPixel(ctx, \1, \2, "\1", "\2", \3);', + code) + + code = re.sub(r'@assert throws (\S+_ERR) (.*);', + lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.%s, "should throw %s");' + % (m.group(2), m.group(1), m.group(1)) + , code) + + code = re.sub(r'@assert throws (\S+Error) (.*);', + lambda m: 'var _thrown = undefined; try {\n %s;\n} catch (e) { _thrown = e }; ok(_thrown && (_thrown instanceof %s), "should throw %s");' + % (m.group(2), m.group(1), m.group(1)) + , code) + + code = re.sub(r'@assert throws (.*);', + lambda m: 'try { var _thrown = false;\n %s;\n} catch (e) { _thrown = true; } finally { ok(_thrown, "should throw exception"); }' + % (m.group(1)) + , code) + + code = re.sub(r'@assert (.*) =~ (.*);', + lambda m: 'ok(%s.match(%s), "%s.match(%s)");' + % (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) + , code) + + code = re.sub(r'@assert (.*);', + lambda m: 'ok(%s, "%s");' + % (m.group(1), escapeJS(m.group(1))) + , code) + + code = re.sub(r'((?:^|\n|;)\s*)ok(.*;) @moz-todo', + lambda m: '%stodo%s' + % (m.group(1), m.group(2)) + , code) + + code = re.sub(r'((?:^|\n|;)\s*)(is.*;) @moz-todo', + lambda m: '%stodo_%s' + % (m.group(1), m.group(2)) + , code) + + code = re.sub(r'@moz-UniversalBrowserRead;', + "netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');" + , code) + + code = code.replace('../images/', 'image_') + + assert '@' not in code, '@ not in code:\n%s' % code + + return code + + used_tests = {} + for i in range(len(tests)): + test = tests[i] + + name = test['name'] + print "\r(%s)" % name, " "*32, "\t", + + if name in used_tests: + print "Test %s is defined twice" % name + used_tests[name] = 1 + + mapped_name = None + for mn in sorted(name_mapping.keys(), key=len, reverse=True): + if name.startswith(mn): + mapped_name = "%s/%s" % (name_mapping[mn], name) + break + if not mapped_name: + print "LIKELY ERROR: %s has no defined target directory mapping" % name + if ISOFFSCREENCANVAS: + continue + else: + mapped_name = name + if 'manual' in test: + mapped_name += "-manual" + + cat_total = '' + for cat_part in [''] + name.split('.')[:-1]: + cat_total += cat_part+'.' + if not cat_total in category_names: category_names.append(cat_total) + category_contents_all.setdefault(cat_total, []).append(name) + category_contents_direct.setdefault(cat_total, []).append(name) + + for ref in test.get('testing', []): + if ref not in spec_ids: + print "Test %s uses nonexistent spec point %s" % (name, ref) + spec_refs.setdefault(ref, []).append(name) + #if not (len(test.get('testing', [])) or 'mozilla' in test): + if not test.get('testing', []): + print "Test %s doesn't refer to any spec points" % name + + if test.get('expected', '') == 'green' and re.search(r'@assert pixel .* 0,0,0,0;', test['code']): + print "Probable incorrect pixel test in %s" % name + + code = expand_test_code(test['code']) + + mochitest = not (W3CMODE or 'manual' in test or 'disabled' in test.get('mozilla', {})) + if mochitest: + mochi_code = expand_mochitest_code(test['code']) + + mochi_name = name + if 'mozilla' in test: + if 'throws' in test['mozilla']: + mochi_code = templates['mochitest.exception'] % mochi_code + if 'bug' in test['mozilla']: + mochi_name = "%s - bug %s" % (name, test['mozilla']['bug']) + + if 'desc' in test: + mochi_desc = '<!-- Testing: %s -->\n' % test['desc'] + else: + mochi_desc = '' + + if 'deferTest' in mochi_code: + mochi_setup = '' + mochi_footer = '' + else: + mochi_setup = '' + mochi_footer = 'SimpleTest.finish();\n' + + for f in ['isPixel', 'todo_isPixel', 'deferTest', 'wrapFunction']: + if f in mochi_code: + mochi_setup += templates['mochitest.%s' % f] + else: + if not W3CMODE: + print "Skipping mochitest for %s" % name + mochi_name = '' + mochi_desc = '' + mochi_code = '' + mochi_setup = '' + mochi_footer = '' + + expectation_html = '' + if 'expected' in test and test['expected'] is not None: + expected = test['expected'] + expected_img = None + if expected == 'green': + expected_img = make_flat_image('green-100x50.png', 100, 50, 0,1,0,1) + if W3CMODE: expected_img = "/images/" + expected_img + elif expected == 'clear': + expected_img = make_flat_image('clear-100x50.png', 100, 50, 0,0,0,0) + if W3CMODE: expected_img = "/images/" + expected_img + else: + if ';' in expected: print "Found semicolon in %s" % name + expected = re.sub(r'^size (\d+) (\d+)', + r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)', + expected) + + if mapped_name.endswith("-manual"): + png_name = mapped_name[:-len("-manual")] + else: + png_name = mapped_name + expected += "\nsurface.write_to_png('%s/%s.png')\n" % (IMAGEOUTPUTDIR, png_name) + eval(compile(expected, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo}) + expected_img = "%s.png" % name + + if expected_img: + expectation_html = ('<p class="output expectedtext">Expected output:' + + '<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img)) + + canvas = test.get('canvas', 'width="100" height="50"') + + prev = tests[i-1]['name'] if i != 0 else 'index' + next = tests[i+1]['name'] if i != len(tests)-1 else 'index' + + name_wrapped = name.replace('.', '.​') # (see https://bugzilla.mozilla.org/show_bug.cgi?id=376188) + + refs = ''.join('<li><a href="%s/canvas.html#testrefs.%s">%s</a>\n' % (SPECOUTPUTPATH, n,n) for n in test.get('testing', [])) + if not W3CMODE and 'mozilla' in test and 'bug' in test['mozilla']: + refs += '<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=%d">Bugzilla</a>' % test['mozilla']['bug'] + + notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else '' + + scripts = '' + for s in test.get('scripts', []): + scripts += '<script src="%s"></script>\n' % (s) + + images = '' + for i in test.get('images', []): + id = i.split('/')[-1] + if '/' not in i: + used_images[i] = 1 + i = '../images/%s' % i + images += '<img src="%s" id="%s" class="resource">\n' % (i,id) + mochi_images = images.replace('../images/', 'image_') + if W3CMODE: images = images.replace("../images/", "/images/") + + fonts = '' + fonthack = '' + for i in test.get('fonts', []): + fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i) + # Browsers require the font to actually be used in the page + if test.get('fonthack', 1): + fonthack += '<span style="font-family: %s; position: absolute; visibility: hidden">A</span>\n' % i + if fonts: + fonts = '<style>\n%s</style>\n' % fonts + + fallback = test.get('fallback', '<p class="fallback">FAIL (fallback content)</p>') + + desc = test.get('desc', '') + escaped_desc = simpleEscapeJS(desc) + template_params = { + 'name':name, 'name_wrapped':name_wrapped, 'backrefs':backref_html(name), + 'mapped_name':mapped_name, + 'desc':desc, 'escaped_desc':escaped_desc, + 'prev':prev, 'next':next, 'refs':refs, 'notes':notes, 'images':images, + 'fonts':fonts, 'fonthack':fonthack, + 'canvas':canvas, 'expected':expectation_html, 'code':code, 'scripts':scripts, + 'mochi_name':mochi_name, 'mochi_desc':mochi_desc, 'mochi_code':mochi_code, + 'mochi_setup':mochi_setup, 'mochi_footer':mochi_footer, 'mochi_images':mochi_images, + 'fallback':fallback + } + + if W3CMODE: + f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, mapped_name), 'w', 'utf-8') + f.write(templates['w3c'] % template_params) + if ISOFFSCREENCANVAS: + f = codecs.open('%s/%s.worker.js' % (TESTOUTPUTDIR, mapped_name), 'w', 'utf-8') + f.write(templates['w3cworker'] % template_params) + else: + f = codecs.open('%s/%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8') + f.write(templates['standalone'] % template_params) + + f = codecs.open('%s/framed.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8') + f.write(templates['framed'] % template_params) + + f = codecs.open('%s/minimal.%s.html' % (TESTOUTPUTDIR, name), 'w', 'utf-8') + f.write(templates['minimal'] % template_params) + + if mochitest: + mochitests.append(name) + f = codecs.open('%s/mochitests/test_%s.html' % (MISCOUTPUTDIR, name), 'w', 'utf-8') + f.write(templates['mochitest'] % template_params) + + def write_mochitest_makefile(): + f = open('%s/mochitests/Makefile.in' % MISCOUTPUTDIR, 'w') + f.write(templates['mochitest.Makefile']) + files = ['test_%s.html' % n for n in mochitests] + ['image_%s' % n for n in used_images] + chunksize = 100 + chunks = [] + for i in range(0, len(files), chunksize): + chunk = files[i:i+chunksize] + name = '_TEST_FILES_%d' % (i / chunksize) + chunks.append(name) + f.write('%s = \\\n' % name) + for file in chunk: f.write('\t%s \\\n' % file) + f.write('\t$(NULL)\n\n') + f.write('# split up into groups to work around command-line length limits\n') + for name in chunks: + f.write('libs:: $(%s)\n\t$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)\n\n' % name) + + if not W3CMODE: + for i in used_images: + shutil.copyfile("../../images/%s" % i, "%s/mochitests/image_%s" % (MISCOUTPUTDIR, i)) + write_mochitest_makefile() + + print + + def write_index(): + f = open('%s/index.html' % TESTOUTPUTDIR, 'w') + f.write(templates['index.w3c' if W3CMODE else 'index'] % { 'updated':time.strftime('%Y-%m-%d', time.gmtime()) }) + f.write('\n<ul class="testlist">\n') + depth = 1 + for category in category_names: + name = category[1:-1] or '' + count = len(category_contents_all[category]) + new_depth = category.count('.') + while new_depth < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1 + f.write(' '*depth + templates['index.w3c.category.item' if W3CMODE else 'index.category.item'] % (name or 'all', name, count, '' if count==1 else 's')) + while new_depth+1 > depth: f.write(' '*depth + '<ul>\n'); depth += 1 + for item in category_contents_direct.get(category, []): + f.write(' '*depth + '<li><a href="%s.html">%s</a>\n' % (item, item) ) + while 0 < depth: f.write(' '*(depth-1) + '</ul>\n'); depth -= 1 + + def write_category_indexes(): + for category in category_names: + name = (category[1:-1] or 'all') + + f = open('%s/index.%s.html' % (TESTOUTPUTDIR, name), 'w') + f.write(templates['index.w3c.frame' if W3CMODE else 'index.frame'] % { 'backrefs':backref_html(name), 'category':name }) + for item in category_contents_all[category]: + f.write(templates['index.w3c.frame.item' if W3CMODE else 'index.frame.item'] % item) + + def write_reportgen(): + f = open('%s/reportgen.html' % MISCOUTPUTDIR, 'w') + items_text = ',\n'.join(('"%s"' % item) for item in category_contents_all['.']) + f.write(templates['reportgen'] % {'items':items_text }) + + def write_results(): + results = {} + uas = [] + uastrings = {} + for item in category_contents_all['.']: results[item] = {} + + f = open('%s/results.html' % MISCOUTPUTDIR, 'w') + f.write(templates['results']) + + if not os.path.exists('results.yaml'): + print "Can't find results.yaml" + else: + for resultset in yaml.load(open('results.yaml', "r").read()): + #title = "%s (%s)" % (resultset['ua'], resultset['time']) + title = resultset['name'] + #assert title not in uas # don't allow repetitions + if title not in uas: + uas.append(title) + uastrings[title] = resultset['ua'] + else: + assert uastrings[title] == resultset['ua'] + for r in resultset['results']: + if r['id'] not in results: + print 'Skipping results for removed test %s' % r['id'] + continue + results[r['id']][title] = ( + r['status'].lower(), + re.sub(r'%(..)', lambda m: chr(int(m.group(1), 16)), + re.sub(r'%u(....)', lambda m: unichr(int(m.group(1), 16)), + r['notes'])).encode('utf8') + ) + + passes = {} + for ua in uas: + f.write('<th title="%s">%s\n' % (uastrings[ua], ua)) + passes[ua] = 0 + for id in category_contents_all['.']: + f.write('<tr><td><a href="#%s" id="%s">#</a> <a href="%s.html">%s</a>\n' % (id, id, id, id)) + for ua in uas: + status, details = results[id].get(ua, ('', '')) + f.write('<td class="r %s"><ul class="d">%s</ul>\n' % (status, details)) + if status == 'pass': passes[ua] += 1 + f.write('<tr><th>Passes\n') + for ua in uas: + f.write('<td>%.1f%%\n' % ((100.0 * passes[ua]) / len(category_contents_all['.']))) + f.write('<tr><td>\n') + for ua in uas: + f.write('<td>%s\n' % ua) + f.write('</table>\n') + + def getNodeText(node): + t, offsets = '', [] + + # Skip over any previous annotations we added + if node.nodeType == node.ELEMENT_NODE and 'testrefs' in node.getAttribute('class').split(' '): + return t, offsets + + if node.nodeType == node.TEXT_NODE: + val = node.nodeValue + val = val.replace(unichr(0xa0), ' ') # replace s + t += val + offsets += [ (node, len(node.nodeValue)) ] + for n in node.childNodes: + child_t, child_offsets = getNodeText(n) + t += child_t + offsets += child_offsets + return t, offsets + + def htmlSerializer(element): + element.normalize() + rv = [] + specialtext = ['style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'noscript'] + empty = ['area', 'base', 'basefont', 'bgsound', 'br', 'col', 'embed', 'frame', + 'hr', 'img', 'input', 'link', 'meta', 'param', 'spacer', 'wbr'] + + def serializeElement(element): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + rv.append("<!DOCTYPE %s>" % element.name) + elif element.nodeType == Node.DOCUMENT_NODE: + for child in element.childNodes: + serializeElement(child) + elif element.nodeType == Node.COMMENT_NODE: + rv.append("<!--%s-->" % element.nodeValue) + elif element.nodeType == Node.TEXT_NODE: + unescaped = False + n = element.parentNode + while n is not None: + if n.nodeName in specialtext: + unescaped = True + break + n = n.parentNode + if unescaped: + rv.append(element.nodeValue) + else: + rv.append(escapeHTML(element.nodeValue)) + else: + rv.append("<%s" % element.nodeName) + if element.hasAttributes(): + for name, value in element.attributes.items(): + rv.append(' %s="%s"' % (name, escapeHTML(value))) + rv.append(">") + if element.nodeName not in empty: + for child in element.childNodes: + serializeElement(child) + rv.append("</%s>" % element.nodeName) + serializeElement(element) + return '<!DOCTYPE html>\n' + ''.join(rv) + + def write_annotated_spec(): + # Load the stripped-down XHTMLised copy of the spec + doc = xml.dom.minidom.parse(open('current-work-canvas.xhtml', 'r')) + + # Insert our new stylesheet + n = doc.getElementsByTagName('head')[0].appendChild(doc.createElement('link')) + n.setAttribute('rel', 'stylesheet') + n.setAttribute('href', '../common/canvas-spec.css' if W3CMODE else '../spectest.css') + n.setAttribute('type', 'text/css') + + spec_assertion_patterns = [] + for a in spec_assertions: + # Warn about problems + if a['id'] not in spec_refs: + print "Unused spec statement %s" % a['id'] + + pattern_text = a['text'] + + if 'keyword' in a: + # Explicit keyword override + keyword = a['keyword'] + else: + # Extract the marked keywords, and remove the markers + keyword = 'none' + for kw in ['must', 'should', 'required']: + if ('*%s*' % kw) in pattern_text: + keyword = kw + pattern_text = pattern_text.replace('*%s*' % kw, kw) + break + # Make sure there wasn't >1 keyword + for kw in ['must', 'should', 'required']: + assert('*%s*' % kw not in pattern_text) + + # Convert the special pattern format into regexp syntax + pattern_text = (pattern_text. + # Escape relevant characters + replace('*', r'\*'). + replace('+', r'\+'). + replace('.', r'\.'). + replace('(', r'\('). + replace(')', r'\)'). + replace('[', r'\['). + replace(']', r'\]'). + # Convert special sequences back into unescaped regexp code + replace(' ', r'\s+'). + replace(r'<\.\.\.>', r'.+'). + replace('<^>', r'()'). + replace('<eol>', r'\s*?\n') + ) + pattern = re.compile(pattern_text, re.S) + spec_assertion_patterns.append( (a['id'], pattern, keyword, a.get('previously', None)) ) + matched_assertions = {} + + def process_element(e): + if e.nodeType == e.ELEMENT_NODE and (e.getAttribute('class') == 'impl' or e.hasAttribute('data-component')): + for c in e.childNodes: + process_element(c) + return + + t, offsets = getNodeText(e) + for id, pattern, keyword, previously in spec_assertion_patterns: + m = pattern.search(t) + if m: + # When the pattern-match isn't enough to uniquely identify a sentence, + # allow explicit back-references to earlier paragraphs + if previously: + if len(previously) >= 3: + n, text, exp = previously + else: + n, text = previously + exp = True + node = e + while n and node.previousSibling: + node = node.previousSibling + n -= 1 + if (text not in getNodeText(node)[0]) == exp: + continue # discard this match + + if id in matched_assertions: + print "Spec statement %s matches multiple places" % id + matched_assertions[id] = True + + if m.lastindex != 1: + print "Spec statement %s has incorrect number of match groups" % id + + end = m.end(1) + end_node = None + for end_node, o in offsets: + if end < o: + break + end -= o + assert(end_node) + + n1 = doc.createElement('span') + n1.setAttribute('class', 'testrefs kw-%s' % keyword) + n1.setAttribute('id', 'testrefs.%s' % id) + n1.appendChild(doc.createTextNode(' ')) + + n = n1.appendChild(doc.createElement('a')) + n.setAttribute('href', '#testrefs.%s' % id) + n.setAttribute('title', id) + n.appendChild(doc.createTextNode('#')) + + n1.appendChild(doc.createTextNode(' ')) + for test_id in spec_refs.get(id, []): + n = n1.appendChild(doc.createElement('a')) + n.setAttribute('href', '../canvas/%s.html' % test_id) + n.appendChild(doc.createTextNode(test_id)) + n1.appendChild(doc.createTextNode(' ')) + n0 = doc.createTextNode(end_node.nodeValue[:end]) + n2 = doc.createTextNode(end_node.nodeValue[end:]) + + p = end_node.parentNode + p.replaceChild(n2, end_node) + p.insertBefore(n1, n2) + p.insertBefore(n0, n1) + + t, offsets = getNodeText(e) + + for e in doc.getElementsByTagName('body')[0].childNodes: + process_element(e) + + for s in spec_assertions: + if s['id'] not in matched_assertions: + print "Annotation incomplete: Unmatched spec statement %s" % s['id'] + + # Convert from XHTML back to HTML + doc.documentElement.removeAttribute('xmlns') + doc.documentElement.setAttribute('lang', doc.documentElement.getAttribute('xml:lang')) + + head = doc.documentElement.getElementsByTagName('head')[0] + head.insertBefore(doc.createElement('meta'), head.firstChild).setAttribute('charset', 'UTF-8') + + f = codecs.open('%s/canvas.html' % SPECOUTPUTDIR, 'w', 'utf-8') + f.write(htmlSerializer(doc)) + + if not W3CMODE: + write_index() + write_category_indexes() + write_reportgen() + write_results() + write_annotated_spec()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/name2dir.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/name2dir.yaml new file mode 100644 index 0000000..c0508dd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/name2dir.yaml
@@ -0,0 +1,46 @@ +2d.transformation: "transformations" +2d.composite: "compositing" +2d.coordinatespace: "conformance-requirements" +2d.missingargs: "conformance-requirements" +2d.type.delete: "conformance-requirements" +2d.voidreturn: "conformance-requirements" +2d.drawImage: "drawing-images-to-the-canvas" +2d.clearRect: "drawing-rectangles-to-the-canvas" +2d.fillRect: "drawing-rectangles-to-the-canvas" +2d.strokeRect: "drawing-rectangles-to-the-canvas" +2d.text.draw: "drawing-text-to-the-canvas" +2d.text.draw.baseline.alphabetic: "drawing-text-to-the-canvas" +2d.text.draw.space.basic: "drawing-text-to-the-canvas" +2d.text.draw.space.collapse: "drawing-text-to-the-canvas" +2d.text.measure: "drawing-text-to-the-canvas" +2d.fillStyle: "fill-and-stroke-styles" +2d.gradient: "fill-and-stroke-styles" +2d.pattern: "fill-and-stroke-styles" +2d.strokeStyle: "fill-and-stroke-styles" +2d.line: "line-styles" +2d.path: "path-objects" +2d.imageData: "pixel-manipulation" +2d.shadow: "shadows" +2d.text.align: "text-styles" +2d.text.baseline: "text-styles" +2d.text.font: "text-styles" +2d.text.draw.baseline: "text-styles" +2d.text.draw.space: "text-styles" +2d.text.measure.width.space: "text-styles" +2d.text.draw.space.collapse.end: "text-styles" +2d.text.draw.space.collapse.other: "text-styles" +2d.text.draw.space.collapse.space: "text-styles" +2d.text.draw.space.collapse.start: "text-styles" +2d.state: "the-canvas-state" +2d.canvas: "../html/semantics/embedded-content/the-canvas-element/" +2d.getcontext: "../html/semantics/embedded-content/the-canvas-element/" +2d.scaled: "../html/semantics/embedded-content/the-canvas-element/" +2d.type: "../html/semantics/embedded-content/the-canvas-element/" +context: "../html/semantics/embedded-content/the-canvas-element/" +fallback: "../html/semantics/embedded-content/the-canvas-element/" +initial: "../html/semantics/embedded-content/the-canvas-element/" +security: "../html/semantics/embedded-content/the-canvas-element/" +size: "../html/semantics/embedded-content/the-canvas-element/" +toBlob: "../html/semantics/embedded-content/the-canvas-element/" +toDataURL: "../html/semantics/embedded-content/the-canvas-element/" +type: "../html/semantics/embedded-content/the-canvas-element/"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/spec.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/spec.yaml new file mode 100644 index 0000000..eb46206 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/spec.yaml
@@ -0,0 +1,719 @@ +# Extracts from http://www.whatwg.org/specs/web-apps/current-work/ +# +# (c) Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. +# You are granted a license to use, reproduce and create derivative works of this document. + +assertions: + - id: canvas.type + text: "interface HTMLCanvasElement<^> : HTMLElement {" + - id: size.width + text: "interface HTMLCanvasElement<...>attribute unsigned long width;<^>" + - id: size.height + text: "interface HTMLCanvasElement<...>attribute unsigned long height;<^>" + - id: canvas.getContext + text: "interface HTMLCanvasElement<...>object\\? getContext(in DOMString contextId, in any... args);<^>" + - id: fallback + text: "The contents of the canvas element, if any, are the element's fallback content<^>." + - id: size.nonnegativeinteger + text: "The rules for parsing non-negative integers *must* be used to obtain their numeric values<^>." + - id: size.missing + text: "If an attribute is missing<^>, <...> then the default value *must* be used instead." + - id: size.error + text: "if parsing its value returns an error<^>, then the default value *must* be used instead." + - id: size.default + text: "The width attribute defaults to 300, and the height attribute defaults to 150<^>." + - id: size.css + text: "the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size<^>." + - id: initial.reset + text: "When the canvas element is created, and subsequently whenever the width and height attributes are set (whether to a new value or to the previous value), the bitmap and any associated contexts *must* be cleared back to their initial state <...><^>." + - id: initial.colour + text: "When the canvas is initialized, its bitmap *must* be cleared to transparent black<^>." + - id: size.reflect + text: "The width and height IDL attributes *must* reflect the respective content attributes of the same name<^>," + + - id: context.unrecognised + text: "If contextId is not the name of a context supported by the user agent, return null and abort these steps<^>." + - id: context.unique + text: "If the getContext() method has already been invoked on this element for the same contextId, return the same object as was returned that time, and abort these steps<^>." + - id: context.2d + text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object<^>." + - id: context.2d.extraargs + text: "When the getContext() method of a canvas element is to return a new object for the contextId 2d, the user agent *must* return a new CanvasRenderingContext2D object. Any additional arguments are ignored<^>." + + - id: toDataURL.noarguments + text: "When a user agent is to create a serialization of the image as a file, <...> if there are no arguments, in the PNG format<^>." + - id: toDataURL.zerosize + text: "If the canvas has no pixels (i.e. either its horizontal dimension or its vertical dimension is zero) then return the string \"data:,\"<^> and abort these steps." + - id: toDataURL.witharguments + text: "If arguments is not empty, the first value must be interpreted as a MIME type giving the format to use<^>." + - id: toDataURL.noalpha + text: "For image types that do not support an alpha channel, the serialized image *must* be the canvas image composited onto a solid black background using the source-over operator<^>." + - id: toDataURL.png + text: "User agents *must* support PNG (\"image/png\")<^>." + - id: toDataURL.unrecognised + text: "If the user agent does not support the requested type, it *must* create the file using the PNG format<^>." + - id: toDataURL.lowercase + text: "User agents *must* convert the provided type to ASCII lowercase before establishing if they support that type<^>." + - id: toDataURL.jpeg + previously: [ 0, "image/png", false ] + text: "image/jpeg<^>" + - id: toDataURL.jpeg.quality + text: "The second argument, if it is a number in the range 0.0 to 1.0 inclusive, *must* be treated as the desired quality level<^>." + - id: toDataURL.jpeg.nan + text: "If it is not a number<^> <...>, the user agent *must* use its default value, as if the argument had been omitted." + - id: toDataURL.jpeg.range + text: "If it is <...> outside that range<^>, the user agent *must* use its default value, as if the argument had been omitted." + - id: toDataURL.arguments + text: "Other arguments *must* be ignored and must not cause the user agent to raise an exception<^>." + + - id: 2d.coordinatespace + text: "flat Cartesian surface whose origin (0,0) is at the top left corner, with the coordinate space having x values increasing when going right, and y values increasing when going down<^>." + - id: context.2d.type + text: "interface CanvasRenderingContext2D<^> {" + - id: 2d.canvasGradient.type + text: "interface CanvasGradient<^> {" + - id: 2d.imageData.type + text: "interface ImageData<^> {" + - id: 2d.canvas.attribute + text: "readonly<^> attribute HTMLCanvasElement canvas;" + - id: 2d.canvas + text: "The canvas attribute *must* return the canvas element that the context paints on<^>." + - id: 2d.nonfinite + text: "Except where otherwise specified, for the 2D context interface, any method call with a numeric argument whose value is infinite or a NaN value *must* be ignored<^>." + + - id: 2d.currentColor.onset + text: "Whenever the CSS value currentColor is used as a color in this API, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is the computed value of the 'color' property on the element in question at the time that the color is specified<^>" + - id: 2d.currentColor.outofdoc + text: "If the computed value of the 'color' property is undefined for a particular case (e.g. because the element is not in a Document), then the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is fully opaque black<^>." + - id: 2d.currentColor.gradient + text: "In the case of addColorStop() on CanvasGradient, the \"computed value of the 'color' property\" for the purposes of determining the computed value of the currentColor keyword is always fully opaque black<^> (there is no associated element)." + + - id: 2d.state.transformation + text: "The current transformation matrix<^>." + - id: 2d.state.clip + text: "The current clipping region<^>." + - meta: | + for s in [ + 'strokeStyle', 'fillStyle', 'globalAlpha', + 'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', + 'shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor', + 'globalCompositeOperation', + 'font', 'textAlign', 'textBaseline' + ]: + assertions.append( { + 'id': '2d.state.%s' % s, + 'text': 'The current values of the following attributes:<...>%s<^>' % s + } ) + - id: 2d.state.path + text: "The current path<^> <...> are not part of the drawing state." + - id: 2d.state.bitmap + text: "The <...> current bitmap<^> are not part of the drawing state." + + - id: 2d.state.save + text: "The save() method *must* push a copy of the current drawing state onto the drawing state stack<^>." + - id: 2d.state.restore + text: "The restore() method *must* pop the top entry in the drawing state stack, and reset the drawing state it describes<^>." + - id: 2d.state.restore.underflow + text: "If there is no saved state, the method *must* do nothing<^>." + + - id: 2d.transformation.initial + text: "When the context is created, the transformation matrix *must* initially be the identity transform<^>." + - id: 2d.transformation.order + text: "The transformations *must* be performed in reverse order<^>." + - id: 2d.transformation.scale + text: "The scale(x, y) method *must* add the scaling transformation described by the arguments to the transformation matrix<^>." + - id: 2d.transformation.scale.multiple + text: "The factors are multiples<^>." + - id: 2d.transformation.rotate + text: "The rotate(angle) method *must* add the rotation transformation described by the argument to the transformation matrix<^>." + - id: 2d.transformation.rotate.direction + text: "The angle argument represents a clockwise rotation angle<^>" + - id: 2d.transformation.rotate.radians + text: "The angle argument <...> expressed in radians<^>." + - id: 2d.transformation.translate + text: "The translate(x, y) method *must* add the translation transformation described by the arguments to the transformation matrix<^>." + - id: 2d.transformation.transform + text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by<^>:" + - id: 2d.transformation.transform.multiply + text: "The transform(a, b, c, d, e, f) method *must* replace the current transformation matrix with the result of multiplying<^> the current transformation matrix with the matrix described by:" + - id: 2d.transformation.setTransform + text: "The setTransform(a, b, c, d, e, f) method *must* <...> invoke the transform(a, b, c, d, e, f) method with the same arguments<^>" + - id: 2d.transformation.setTransform.identity + text: "The setTransform(a, b, c, d, e, f) method *must* reset the current transform to the identity matrix<^>, " + + + - id: 2d.composite.operation + text: "All drawing operations are affected by the global compositing attributes, globalAlpha and globalCompositeOperation<^>." + + - id: 2d.composite.globalAlpha.shape + text: "The globalAlpha attribute gives an alpha value that is applied to shapes<^> and images before they are composited onto the canvas." + - id: 2d.composite.globalAlpha.image + text: "The globalAlpha attribute gives an alpha value that is applied to shapes and images<^> before they are composited onto the canvas." + - id: 2d.composite.globalAlpha.range + text: "The value must be in the range from 0.0 (fully transparent) to 1.0 (no additional transparency). If an attempt is made to set the attribute to a value outside this range, including Infinity and Not-a-Number (NaN) values, the attribute *must* retain its previous value<^>." + - id: 2d.composite.globalAlpha.default + text: "When the context is created, the globalAlpha attribute *must* initially have the value 1.0<^>." + + - id: 2d.composite.operation.shape + text: "The globalCompositeOperation attribute sets how shapes<^> and images are drawn onto the existing bitmap," + - id: 2d.composite.operation.image + text: "The globalCompositeOperation attribute sets how shapes and images<^> are drawn onto the existing bitmap," + + - id: 2d.composite.source-atop + text: "source-atop<^><eol>" + - id: 2d.composite.source-in + text: "source-in<^><eol>" + - id: 2d.composite.source-out + text: "source-out<^><eol>" + - id: 2d.composite.source-over + text: "source-over (default)<^><eol>" + - id: 2d.composite.destination-atop + text: "destination-atop<^><eol>" + - id: 2d.composite.destination-in + text: "destination-in<^><eol>" + - id: 2d.composite.destination-out + text: "destination-out<^><eol>" + - id: 2d.composite.destination-over + text: "destination-over<^><eol>" + - id: 2d.composite.lighter + text: "lighter<^><eol>" + - id: 2d.composite.copy + text: "copy<^><eol>" + - id: 2d.composite.xor + text: "xor<^><eol>" + - id: 2d.composite.clear + text: "clear<^><eol>" + + - id: 2d.composite.operation.casesensitive + text: "These values are all case-sensitive<^> <...> they *must* be used exactly as shown." + - id: 2d.composite.operation.exact + text: "User agents *must* not recognize values that are not a case-sensitive match for one of the values given above<^>." + - id: 2d.composite.operation.porterduff + text: "The operators in the above list *must* be treated as described by the Porter-Duff operator given at the start of their description (e.g. A over B)<^>." + - id: 2d.composite.operation.unrecognised + text: "On setting, if the user agent does not recognize the specified value, it *must* be ignored, leaving the value of globalCompositeOperation unaffected<^>." + - id: 2d.composite.operation.default + text: "When the context is created, the globalCompositeOperation attribute *must* initially have the value source-over<^>." + + + - id: 2d.colours.parse + text: "On setting, strings *must* be parsed as CSS <color> values and the color assigned<^>," + - id: 2d.gradient.assign + text: "On setting, <...> CanvasGradient<^> and CanvasPattern objects *must* be assigned themselves." + - id: 2d.pattern.assign + text: "On setting, <...> CanvasGradient and CanvasPattern<^> objects *must* be assigned themselves." + - id: 2d.colours.invalidstring + text: "If the value is a string but cannot be parsed as a CSS <color> value<^>, <...> then it *must* be ignored, and the attribute must retain its previous value." + - id: 2d.colours.invalidtype + text: "If the value is <...> neither a string, a CanvasGradient, nor a CanvasPattern<^>, then it *must* be ignored, and the attribute must retain its previous value." + - id: 2d.colours.getcolour + text: "On getting, if the value is a color, then the serialization of the color *must* be returned<^>." + - id: 2d.gradient.object + text: "if it is not a color but a CanvasGradient<^> or CanvasPattern, then the respective object *must* be returned." + - id: 2d.pattern.object + text: "if it is not a color but a CanvasGradient or CanvasPattern<^>, then the respective object *must* be returned." + - id: 2d.serializecolour.solid + text: "if it has alpha equal to 1.0, then the string is a lowercase six-digit hex value<^>" + - id: 2d.serializecolour.transparent + text: "Otherwise, the color value has alpha less than 1.0, and the string is the color value in the CSS rgba() functional-notation format<^>:" + - id: 2d.colours.default + text: "When the context is created, the strokeStyle and fillStyle attributes *must* initially have the string value #000000<^>." + + - id: 2d.gradient.interpolate.linear + text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated<^> over the RGBA space without premultiplying the alpha value to find the color to use at that offset." + - id: 2d.gradient.interpolate.alpha + text: "Between each such stop, the colors and the alpha component *must* be linearly interpolated over the RGBA space without premultiplying the alpha value<^> to find the color to use at that offset." + - id: 2d.gradient.outside.first + text: "Before the first stop, the color *must* be the color of the first stop<^>." + - id: 2d.gradient.outside.last + text: "After the last stop, the color *must* be the color of the last stop<^>." + - id: 2d.gradient.empty + text: "When there are no stops, the gradient is transparent black<^>." + + + - id: 2d.gradient.invalidoffset + text: "If the offset is less than 0, greater than 1, infinite, or NaN, then an INDEX_SIZE_ERR exception *must* be raised<^>." + - id: 2d.gradient.invalidcolour + text: "If the color cannot be parsed as a CSS <color> value, then a SYNTAX_ERR exception *must* be raised<^>." + - id: 2d.gradient.update + text: "Otherwise, the gradient *must* have a new stop placed, at offset offset relative to the whole gradient, and with the color obtained by parsing color as a CSS <color> value<^>." + - id: 2d.gradient.interpolate.overlap + text: "If multiple stops are added at the same offset on a gradient, they *must* be placed in the order added, with the first one closest to the start of the gradient, <...><^>." + + - id: 2d.gradient.linear.nonfinite + text: "If any of the arguments to createLinearGradient() are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception<^>." + - id: 2d.gradient.linear.return + text: "Otherwise, the method *must* return a linear CanvasGradient initialized with the specified line<^>." + - id: 2d.gradient.linear.rendering + text: "Linear gradients *must* be rendered such that all points on a line perpendicular to the line that crosses the start and end points have the color at the point where those two lines cross (with the colors coming from the interpolation and extrapolation described above)<^>." + - id: 2d.gradient.linear.transform + text: "The points in the linear gradient *must* be transformed as described by the current transformation matrix when rendering<^>." + - id: 2d.gradient.linear.zerosize + text: "If x0 = x1 and y0 = y1, then the linear gradient *must* paint nothing<^>." + + - id: 2d.gradient.radial.nonfinite + text: "If any of the arguments are infinite or NaN, a NOT_SUPPORTED_ERR exception *must* be raised<^>." + - id: 2d.gradient.radial.negative + text: "If either of r0 or r1 are negative, an INDEX_SIZE_ERR exception *must* be raised<^>." + - id: 2d.gradient.radial.return + text: "Otherwise, the method *must* return a radial CanvasGradient initialized with the two specified circles<^>." + - id: 2d.gradient.radial.rendering + text: "Radial gradients *must* be rendered by following these steps<^>:" + - id: 2d.gradient.radial.equal + text: "If x0 = x1 and y0 = y1 and r0 = r1, then the radial gradient *must* paint nothing<^>." + - id: 2d.gradient.extent + text: "Gradients *must* be painted only where the relevant stroking or filling effects requires that they be drawn<^>." + - id: 2d.gradient.radial.transform + text: "The points in the radial gradient *must* be transformed as described by the current transformation matrix when rendering<^>." + + + - id: 2d.pattern.modify + text: "Modifying this image after calling the createPattern() method *must* not affect the pattern<^>." + - id: 2d.pattern.missing + text: "If the empty string is specified, repeat *must* be assumed<^>." + - id: 2d.pattern.unrecognised + text: "If an unrecognized value is given, then the user agent *must* raise a SYNTAX_ERR exception<^>." + - id: 2d.pattern.exact + text: "User agents *must* recognize the four values described above exactly (e.g. they must not do case folding)<^>." + - id: 2d.pattern.return + text: "the method *must* return a CanvasPattern object suitably initialized<^>." + - id: 2d.pattern.IDL + text: "CanvasPattern createPattern(in HTMLImageElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLCanvasElement image, in DOMString repetition);<...>CanvasPattern createPattern(in HTMLVideoElement image, in DOMString repetition);<^>" + - id: 2d.pattern.incomplete.image + text: "If the image argument is an HTMLImageElement object that is not fully decodable<^><...> then the implementation *must* return null." + - id: 2d.pattern.incomplete.video + previously: [ 6, "createPattern" ] + text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA<^>, then the implementation *must* return null." + - id: 2d.pattern.zerocanvas + previously: [ 10, "createPattern" ] + text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* raise an INVALID_STATE_ERR exception<^>." + - id: 2d.pattern.painting + text: "Patterns *must* be painted so that the top left of the first image is anchored at the origin of the coordinate space, and images are then repeated horizontally to the left and right (if the repeat-x string was specified) or vertically up and down (if the repeat-y string was specified) or in all four directions all over the canvas (if the repeat string was specified)<^>." + - id: 2d.pattern.unscaled + text: "The images are not scaled by this process; one CSS pixel of the image *must* be painted on one coordinate space unit<^>." + - id: 2d.pattern.extent + text: "patterns *must* actually be painted only where the stroking or filling effect requires that they be drawn<^>, and are affected by the current transformation matrix." + - id: 2d.pattern.animated.image + text: "When the createPattern() method is passed an animated image as its image argument, the user agent must use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation<^>." + - id: 2d.pattern.animated.video + previously: [ 4, "createPattern" ] + text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image<^>," + - id: 2d.pattern.video.size + previously: [ 4, "createPattern" ] + text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)<^>." + + + - id: 2d.lineWidth + text: "The lineWidth attribute gives the width of lines, in coordinate space units<^>." + - id: 2d.lineWidth.get + text: "The lineWidth attribute <...>. On getting, it *must* return the current value<^>." + - id: 2d.lineWidth.invalid + text: "The lineWidth attribute <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged<^>;" + - id: 2d.lineWidth.set + text: "The lineWidth attribute <...>. On setting, <...> other values *must* change the current value to the new value<^>." + - id: 2d.lineWidth.default + text: "the lineWidth attribute *must* initially have the value 1.0<^>." + - id: 2d.lineCap.end + text: "The lineCap attribute defines the type of endings that UAs will place on the end of lines<^>." + - id: 2d.lineCap.butt + text: "The butt value means that the end of each line has a flat edge perpendicular to the direction of the line (and that no additional line cap is added)<^>." + - id: 2d.lineCap.round + text: "The round value means that a semi-circle with the diameter equal to the width of the line *must* then be added on to the end of the line<^>." + - id: 2d.lineCap.square + text: "The square value means that a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line, *must* be added at the end of each line<^>." + - id: 2d.lineCap.get + previously: [ 2, "The lineCap attribute" ] + text: "On getting, it *must* return the current value<^>." + - id: 2d.lineCap.set + text: "On setting, if the new value is one of the literal strings butt, round, and square, then the current value *must* be changed to the new value<^>;" + - id: 2d.lineCap.invalid + text: "On setting, if the new value is one of the literal strings butt, round, and square, then <...>; other values *must* ignored, leaving the value unchanged<^>." + - id: 2d.lineCap.default + text: "When the context is created, the lineCap attribute *must* initially have the value butt<^>." + - id: 2d.lineJoin.get + previously: [ 2, "lineJoin" ] + text: "On getting, it *must* return the current value<^>." + - id: 2d.lineJoin.set + text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then the current value *must* be changed to the new value<^>;" + - id: 2d.lineJoin.invalid + text: "On setting, if the new value is one of the literal strings bevel, round, and miter, then <...>; other values *must* be ignored, leaving the value unchanged<^>." + - id: 2d.lineJoin.default + text: "When the context is created, the lineJoin attribute *must* initially have the value miter<^>." + - id: 2d.lineJoin.joins + text: "A join exists at any point in a subpath shared by two consecutive lines<^>." + - id: 2d.lineJoin.joinclosed + text: "When a subpath is closed, then a join also exists at its first point (equivalent to its last point) connecting the first and last lines in the subpath<^>." + - id: 2d.lineJoin.common + text: "A filled triangle connecting these two opposite corners with a straight line, with the third point of the triangle being the join point, *must* be rendered at all joins<^>." + - id: 2d.lineJoin.round + text: "The round value means that a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, *must* be rendered at joins<^>." + - id: 2d.lineJoin.bevel + text: "The bevel value means that this is all that is rendered at joins<^>." + - id: 2d.lineJoin.miter + text: "The miter value means that a second filled triangle *must* (if it can given the miter length) be rendered at the join, with one line being the line between the two aforementioned corners, abutting the first triangle, and the other two being continuations of the outside edges of the two joining lines, as long as required to intersect without going over the miter length<^>." + - id: 2d.lineJoin.miterLimit + text: "If the miter length would cause the miter limit ratio to be exceeded, this second triangle *must* not be rendered<^>." + - id: 2d.miterLimit.get + text: "The miter limit <...>. On getting, it *must* return the current value<^>." + - id: 2d.miterLimit.invalid + text: "The miter limit <...>. On setting, zero, negative, infinite, and NaN values *must* be ignored, leaving the value unchanged<^>;" + - id: 2d.miterLimit.set + text: "The miter limit <...>. On setting, <...>; other values *must* change the current value to the new value<^>." + - id: 2d.miterLimit.default + text: "When the context is created, the miterLimit attribute *must* initially have the value 10.0<^>." + + + - id: 2d.shadow.color.initial + text: "When the context is created, the shadowColor attribute initially *must* be fully-transparent black<^>." + - id: 2d.shadow.color.get + text: "On getting, the serialization of the color *must* be returned<^>." + - id: 2d.shadow.color.set + text: "On setting, the new value *must* be parsed as a CSS <color> value and the color assigned<^>." + - id: 2d.shadow.color.invalid + text: "If the value cannot be parsed as a CSS <color> value then it *must* be ignored, and the attribute must retain its previous value<^>." + - id: 2d.shadow.offset.initial + text: "When the context is created, the shadow offset attributes *must* initially have the value 0<^>." + - id: 2d.shadow.offset.get + text: "On getting, they *must* return their current value<^>." + - id: 2d.shadow.offset.set + text: "On setting, the attribute being set *must* be set to the new value<^>," + - id: 2d.shadow.offset.invalid + text: "On setting, <...> if the value is infinite or NaN, in which case the new value *must* be ignored<^>." + - id: 2d.shadow.blur.initial + text: "When the context is created, the shadowBlur attribute *must* initially have the value 0<^>." + - id: 2d.shadow.blur.get + text: "On getting, the attribute *must* return its current value<^>." + - id: 2d.shadow.blur.set + text: "On setting the attribute *must* be set to the new value<^>," + - id: 2d.shadow.blur.invalid + text: "On setting <...> if the value is negative, infinite or NaN, in which case the new value *must* be ignored<^>." + - id: 2d.shadow.enable + text: "Shadows are only drawn if the opacity component of the alpha component of the color of shadowColor is non-zero and either the shadowBlur is non-zero, or the shadowOffsetX is non-zero, or the shadowOffsetY is non-zero<^>." + - id: 2d.shadow.render + text: "When shadows are drawn, they *must* be rendered as follows<^>:" + + - id: 2d.rect.transform + text: "The current transformation matrix *must* be applied to the following four coordinates<^>," + - id: 2d.rect.closed + text: "the following four coordinates, which form the path that *must* then be closed to get the specified rectangle<^>:" + - id: 2d.clearRect + text: "The clearRect(x, y, w, h) method *must* clear the pixels in the specified rectangle that also intersect the current clipping region to a fully transparent black, erasing any previous image<^>." + - id: 2d.fillRect + text: "The fillRect(x, y, w, h) method *must* paint the specified rectangular area using the fillStyle<^>." + - id: 2d.strokeRect + text: "The strokeRect(x, y, w, h) method *must* stroke the specified rectangle's path using the strokeStyle, lineWidth, lineJoin, and (if appropriate) miterLimit attributes<^>." + + + - id: 2d.path.initial + text: "Initially, the context's path *must* have zero subpaths<^>." + - id: 2d.path.transformation + text: "The points and lines added to the path by these methods *must* be transformed according to the current transformation matrix as they are added<^>." + - id: 2d.path.beginPath + text: "The beginPath() method *must* empty the list of subpaths so that the context once again has zero subpaths<^>." + - id: 2d.path.moveTo + text: "The moveTo(x, y) method *must* create a new subpath with the specified point as its first (and only) point<^>." + - id: 2d.path.ensure + text: "When the user agent is to ensure there is a subpath for a coordinate (x, y), the user agent must check to see if the context has any subpaths, and if it does not, then the user agent *must* create a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called<^>." + - id: 2d.path.closePath.empty + text: "The closePath() method *must* do nothing if the context has no subpaths<^>." + - id: 2d.path.closePath.nonempty + text: "The closePath() method <...> *must* mark the last subpath as closed, create a new subpath whose first point is the same as the previous subpath's first point, and finally add this new subpath to the path<^>." + - id: 2d.path.lineTo.empty + text: "The lineTo(x, y) method *must* ensure there is a subpath for (x, y) if the context has no subpaths<^>." + - id: 2d.path.lineTo.nonempty + text: "The lineTo(x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a straight line, and must then add the given point (x, y) to the subpath<^>." + - id: 2d.path.quadratic.empty + text: "The quadraticCurveTo(cpx, cpy, x, y) method *must* ensure there is a subpath for (cpx, cpy)<^>," + - id: 2d.path.quadratic.nonempty + text: "The quadraticCurveTo(cpx, cpy, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a quadratic B<...>zier curve with control point (cpx, cpy), and must then add the given point (x, y) to the subpath<^>." + - id: 2d.path.bezier.empty + text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method *must* ensure there is a subpath for (cp1x, cp1y)<^>," + - id: 2d.path.bezier.nonempty + text: "The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method <...> *must* connect the last point in the subpath to the given point (x, y) using a cubic B<...>zier curve with control points (cp1x, cp1y) and (cp2x, cp2y). Then, it must add the point (x, y) to the subpath<^>." + - id: 2d.path.arcTo.empty + text: "The arcTo(x1, y1, x2, y2, radius) method *must* first ensure there is a subpath for (x1, y1)<^>." + - id: 2d.path.arcTo.negative + previously: [ 2, "arcTo(" ] + text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception<^>." + - id: 2d.path.arcTo.coincide.01 + text: "If the point (x0, y0) is equal to the point (x1, y1)<^>, or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line." + - id: 2d.path.arcTo.coincide.12 + text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2)<^>, or if the radius radius is zero, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line." + - id: 2d.path.arcTo.zeroradius + text: "If the point (x0, y0) is equal to the point (x1, y1), or if the point (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero<^>, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line." + - id: 2d.path.arcTo.collinear + text: "if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line, then the method *must* add the point (x1, y1) to the subpath, and connect that point to the previous point (x0, y0) by a straight line<^>." + - id: 2d.path.arcTo.shape + text: "The method *must* connect the point (x0, y0) to the start tangent point by a straight line, adding the start tangent point to the subpath, and then must connect the start tangent point to the end tangent point by The Arc, adding the end tangent point to the subpath<^>." + + - id: 2d.path.arc.nonempty + text: "If the context has any subpaths, then the method *must* add a straight line from the last point in the subpath to the start point of the arc<^>." + - id: 2d.path.arc.draw + text: "it *must* draw the arc between the start point of the arc and the end point of the arc, and add the start and end points of the arc to the subpath<^>." + - id: 2d.path.arc.zero + text: "If the two points are the same, or if the radius is zero<^>, then the arc is defined as being of zero length in both directions." + - id: 2d.path.arc.negative + previously: [ 2, "anticlockwise" ] + text: "Negative values for radius *must* cause the implementation to raise an INDEX_SIZE_ERR exception<^>." + + - id: 2d.path.rect.subpath + text: "The rect(x, y, w, h) method *must* create a new subpath containing just the four points (x, y), (x+w, y), (x+w, y+h), (x, y+h), with those four points connected by straight lines<^>" + - id: 2d.path.rect.closed + text: "The rect(x, y, w, h) method <...> *must* then mark the subpath as closed<^>." + - id: 2d.path.rect.newsubpath + text: "The rect(x, y, w, h) method <...> *must* then create a new subpath with the point (x, y) as the only point in the subpath<^>." + + - id: 2d.path.fill.basic + text: "The fill() method *must* fill all the subpaths of the current path, using fillStyle, and using the non-zero winding number rule<^>." + - id: 2d.path.fill.closed + text: "Open subpaths *must* be implicitly closed when being filled (without affecting the actual subpaths)<^>." + - id: 2d.path.stroke.basic + text: "The stroke() method *must* calculate the strokes of all the subpaths of the current path, using the lineWidth, lineCap, lineJoin, and (if appropriate) miterLimit attributes, and then fill the combined stroke area using the strokeStyle attribute<^>." + - id: 2d.path.unaffected + text: "Paths, when filled or stroked, *must* be painted without affecting the current path<^>" + - id: 2d.path.subjected + text: "Paths, when filled or stroked, <...> *must* be subject to shadow effects, global alpha, the clipping region, and global composition operators<^>." + + - id: 2d.path.stroke.prune + text: "Zero-length line segments *must* be pruned before stroking a path<^>." + - id: 2d.path.stroke.empty + text: "Empty subpaths *must* be ignored<^>." + + - id: 2d.path.clip.basic + text: "The clip() method *must* create a new clipping region by calculating the intersection of the current clipping region and the area described by the current path, using the non-zero winding number rule<^>." + - id: 2d.path.clip.closed + text: "Open subpaths *must* be implicitly closed when computing the clipping region, without affecting the actual subpaths<^>." + - id: 2d.path.clip.initial + text: "When the context is initialized, the clipping region *must* be set to the rectangle with the top left corner at (0,0) and the width and height of the coordinate space<^>." + - id: 2d.path.isPointInPath + text: "The isPointInPath(x, y) method *must* return true if the point given by the x and y coordinates passed to the method, when treated as coordinates in the canvas coordinate space unaffected by the current transformation, is inside the current path as determined by the non-zero winding number rule; and must return false otherwise<^>." + - id: 2d.path.isPointInPath.edge + text: "The isPointInPath(x, y) method *must* return true if <...>. Points on the path itself are considered to be inside the path<^>." + - id: 2d.path.isPointInPath.nonfinite + text: "If either of the arguments is infinite or NaN, then the method *must* return false<^>." + + # TODO: Focus management + + - id: 2d.text.font.parse + text: "The font IDL attribute, on setting, *must* be parsed the same way as the 'font' property of CSS (but without supporting property-independent style sheet syntax like 'inherit')<^>," + - id: 2d.text.font.lineheight + text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'line-height' component forced to 'normal'<^>," + - id: 2d.text.font.fontsize + text: "The font IDL attribute, on setting, *must* be parsed <...> with the 'font-size' component converted to CSS pixels<^>," + - id: 2d.text.font.systemfonts + text: "The font IDL attribute, on setting, *must* be parsed <...> with system fonts being computed to explicit values<^>." + - id: 2d.text.font.invalid + text: "If the new value is syntactically incorrect (including using property-independent style sheet syntax like 'inherit' or 'initial'), then it *must* be ignored, without assigning a new font value<^>." + + - id: 2d.text.font.fontface + text: "Font names must be interpreted in the context of the canvas element's stylesheets; any fonts embedded using @font-face *must* therefore be available once they are loaded<^>." + - id: 2d.text.font.notfullyloaded + text: "If a font is referenced before it is fully loaded, then it *must* be treated as if it was an unknown font, falling back to another as described by the relevant CSS specifications<^>." + - id: 2d.text.font.get + text: "On getting, the font attribute *must* return the serialized form of the current font of the context (with no 'line-height' component)<^>." + - id: 2d.text.font.default + text: "When the context is created, the font of the context *must* be set to 10px sans-serif<^>." + - id: 2d.text.font.size + text: "When the 'font-size' component is set to lengths using percentages, 'em' or 'ex' units, or the 'larger' or 'smaller' keywords, these *must* be interpreted relative to the computed value of the 'font-size' property of the corresponding canvas element at the time that the attribute is set<^>." + - id: 2d.text.font.weight + text: "When the 'font-weight' component is set to the relative values 'bolder' and 'lighter', these *must* be interpreted relative to the computed value of the 'font-weight' property of the corresponding canvas element at the time that the attribute is set<^>." + - id: 2d.text.font.undefined + text: "If the computed values are undefined for a particular case (e.g. because the canvas element is not in a Document), then the relative keywords *must* be interpreted relative to the normal-weight 10px sans-serif default<^>." + - id: 2d.text.align.get + text: "The textAlign IDL attribute, on getting, *must* return the current value<^>." + - id: 2d.text.align.set + text: "On setting, if the value is one of start, end, left, right, or center, then the value *must* be changed to the new value<^>." + - id: 2d.text.align.invalid + text: "The textAlign IDL attribute, <...> Otherwise, the new value *must* be ignored<^>." + - id: 2d.text.align.default + text: "When the context is created, the textAlign attribute *must* initially have the value start<^>." + - id: 2d.text.baseline.get + text: "The textBaseline IDL attribute, on getting, *must* return the current value<^>." + - id: 2d.text.baseline.set + text: "On setting, if the value is one of top, hanging, middle, alphabetic, ideographic, or bottom, then the value *must* be changed to the new value<^>." + - id: 2d.text.baseline.invalid + text: "The textBaseline IDL attribute, <...> Otherwise, the new value *must* be ignored<^>." + - id: 2d.text.baseline.default + text: "When the context is created, the textBaseline attribute *must* initially have the value alphabetic<^>." + + - id: 2d.text.draw + text: "The fillText() and strokeText() methods <...> when the methods are called, the user agent *must* run the following steps<^>:" + - id: 2d.text.draw.spaces + text: "Replace all the space characters in text with U+0020 SPACE characters<^>." + - id: 2d.text.draw.direction + text: "the 'direction' property of the inline box set to the directionality of the canvas element<^>," + - id: 2d.text.draw.maxwidth + text: "If the maxWidth argument was specified and the hypothetical width of the inline box in the hypothetical line box is greater than maxWidth CSS pixels, then change font to have a more condensed font (if one is available or if a reasonably readable one can be synthesized by applying a horizontal scale factor to the font) or a smaller font, and return to the previous step<^>." + - id: 2d.text.align.left + text: "Let the anchor point's horizontal position be the left edge of the inline box<^>." + - id: 2d.text.align.right + text: "Let the anchor point's horizontal position be the right edge of the inline box<^>." + - id: 2d.text.align.center + text: "Let the anchor point's horizontal position be half way between the left and right edges of the inline box<^>." + + - id: 2d.text.baseline.top + text: "Let the anchor point's vertical position be the top of the em box of the first available font of the inline box<^>." + - id: 2d.text.baseline.hanging + text: "Let the anchor point's vertical position be the hanging baseline of the first available font of the inline box<^>." + - id: 2d.text.baseline.middle + text: "Let the anchor point's vertical position be half way between the bottom and the top of the em box of the first available font of the inline box<^>." + - id: 2d.text.baseline.alphabetic + text: "Let the anchor point's vertical position be the alphabetic baseline of the first available font of the inline box<^>." + - id: 2d.text.baseline.ideographic + text: "Let the anchor point's vertical position be the ideographic baseline of the first available font of the inline box<^>." + - id: 2d.text.baseline.bottom + text: "Let the anchor point's vertical position be the bottom of the em box of the first available font of the inline box<^>." + + - id: 2d.text.draw.fill + text: "For fillText() fillStyle must be applied to the glyphs and strokeStyle *must* be ignored<^>." + - id: 2d.text.draw.stroke + text: "For strokeText() the reverse holds and strokeStyle must be applied to the glyph outlines and fillStyle *must* be ignored<^>." + - id: 2d.text.measure.spaces + text: "When the method is invoked, the user agent *must* replace all the space characters in text with U+0020 SPACE characters<^>," + - id: 2d.text.measure + text: "When the method is invoked, the user agent <...> *must* form a hypothetical infinitely wide CSS line box containing a single inline box containing the text text, with all the properties at their initial values except the 'white-space' property of the inline element set to 'pre' and the 'font' property of the inline element set to the current font of the context as given by the font attribute, and must then return a new TextMetrics object with its width attribute set to the width of that inline box, in CSS pixels<^>." + + - id: 2d.drawImage.defaultdest + text: "If not specified, the dw and dh arguments *must* default to the values of sw and sh, interpreted such that one CSS pixel in the image is treated as one unit in the canvas coordinate space<^>." + - id: 2d.drawImage.defaultsource + text: "If the sx, sy, sw, and sh arguments are omitted, they *must* default to 0, 0, the image's intrinsic width in image pixels, and the image's intrinsic height in image pixels, respectively<^>." + - id: 2d.drawImage.IDL + text: "void drawImage(in HTMLVideoElement image, in double sx, in double sy, in double sw, in double sh, in double dx, in double dy, in double dw, in double dh);<^>" + - id: 2d.drawImage.incomplete.image + text: "If the image argument is an HTMLImageElement object that is not fully decodable<^><...> then the implementation *must* return without drawing anything." + - id: 2d.drawImage.incomplete.video + previously: [ 6, "dw and dh" ] + text: "If the image argument is <...> an HTMLVideoElement object whose readyState attribute is either HAVE_NOTHING or HAVE_METADATA<^>, then the implementation *must* return without drawing anything." + - id: 2d.drawImage.zerocanvas + previously: [ 10, "dw and dh" ] + text: "If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then the implementation *must* return without drawing anything<^>." + - id: 2d.drawImage.zerosource + text: "If one of the sw or sh arguments is zero<^>, the implementation *must* return without drawing anything." + - id: 2d.drawImage.paint + text: "When drawImage() is invoked, the region of the image specified by the source rectangle *must* be painted on the region of the canvas specified by the destination rectangle<^>, after applying the current transformation matrix to the points of the destination rectangle." + - id: 2d.drawImage.original + text: "The original image data of the source image *must* be used, not the image as it is rendered (e.g. width and height attributes on the source element have no effect)<^>." + - id: 2d.drawImage.direction + text: "The image data *must* be processed in the original direction, even if the dimensions given are negative<^>." + - id: 2d.drawImage.self + text: "When a canvas is drawn onto itself, the drawing model requires the source to be copied before the image is drawn back onto the canvas, so it is possible to copy parts of a canvas onto overlapping parts of itself<^>." + - id: 2d.drawImage.animated.image + text: "When the drawImage() method is passed an animated image as its image argument, the user agent *must* use the poster frame of the animation, or, if there is no poster frame, the first frame of the animation<^>." + - id: 2d.drawImage.animated.video + previously: [ 4, "drawImage" ] + text: "When the image argument is an HTMLVideoElement, then the frame at the current playback position *must* be used as the source image<^>," + - id: 2d.drawImage.video.size + previously: [ 4, "drawImage" ] + text: "When the image argument is an HTMLVideoElement, <...> the source image's dimensions *must* be the intrinsic width and intrinsic height of the media resource (i.e. after any aspect-ratio correction has been applied)<^>." + - id: 2d.drawImage.unaffect + text: "Images are painted without affecting the current path<^>" + - id: 2d.drawImage.subject + text: "Images are painted without affecting the current path, and are subject to shadow effects, global alpha, the clipping region, and global composition operators<^>." + + + - id: 2d.imageData.create2.object + text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object<^>" + - id: 2d.imageData.create2.size + text: "When the method is invoked with two arguments sw and sh, it *must* return an ImageData object representing a rectangle with a width in CSS pixels equal to the absolute magnitude of sw and a height in CSS pixels equal to the absolute magnitude of sh<^>." + - id: 2d.imageData.create1.object + text: "When invoked with a single imagedata argument, it *must* return an ImageData object<^>" + - id: 2d.imageData.create1.size + text: "When invoked with a single imagedata argument, it *must* return an ImageData object representing a rectangle with the same dimensions as the ImageData object passed as the argument<^>." + - id: 2d.imageData.create.initial + text: "The ImageData object returned must be filled with transparent black<^>." + + - id: 2d.imageData.get.object + text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object<^>" + - id: 2d.imageData.get.basic + text: "The getImageData(sx, sy, sw, sh) method *must* return an ImageData object representing the underlying pixel data for the area of the canvas denoted by the rectangle whose corners are the four points (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh), in canvas coordinate space units<^>." + - id: 2d.imageData.get.outside + text: "Pixels outside the canvas *must* be returned as transparent black<^>." + - id: 2d.imageData.get.premul + text: "Pixels *must* be returned as non-premultiplied alpha values<^>." + + - id: 2d.imageData.getcreate.nonfinite + text: "If any of the arguments to createImageData() or getImageData() are infinite or NaN<^>, the method *must* instead raise a NOT_SUPPORTED_ERR exception." + - id: 2d.imageData.create.null + text: "ImageData createImageData(in ImageData imagedata);<^>" + - id: 2d.imageData.getcreate.zero + text: "If either the sw or sh arguments are zero, the method *must* instead raise an INDEX_SIZE_ERR exception<^>." + + - id: 2d.imageData.initial + text: "ImageData objects *must* be initialized so that their width attribute is set to w, the number of physical device pixels per row in the image data, their height attribute is set to h, the number of rows in the image data, and their data attribute is initialized to a CanvasPixelArray object holding the image data<^>." + - id: 2d.imageData.one + text: "At least one pixel's worth of image data *must* be returned<^>." + - id: 2d.pixelarray.order + text: "The data *must* be represented in left-to-right order, row by row top to bottom, starting with the top left, with each pixel's red, green, blue, and alpha components being given in that order for each pixel<^>." + - id: 2d.pixelarray.range + text: "Each component of each device pixel represented in this array *must* be in the range 0..255, representing the 8 bit value for that component<^>." + - id: 2d.pixelarray.indexes + text: "The components *must* be assigned consecutive indices starting with 0 for the top left pixel's red component<^>." + - id: 2d.pixelarray.length + text: "The length attribute of a CanvasPixelArray object *must* return this number<^>." + - id: 2d.pixelarray.retrieve + text: "To determine the value of an indexed property index, the user agent *must* return the value of the indexth component in the array<^>." + - id: 2d.pixelarray.modify + text: "To set the value of an existing indexed property index to value value, the value of the indexth component in the array *must* be set to value<^>." + + - id: 2d.imageData.put.nonfinite + text: "If any of the arguments to the method are infinite or NaN, the method *must* raise a NOT_SUPPORTED_ERR exception<^>." + - id: 2d.imageData.put.wrongtype + text: "void putImageData(in ImageData imagedata, in double dx, in double dy);<...>void putImageData(in ImageData imagedata, in double dx, in double dy, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);<^>" + - id: 2d.imageData.put.3arg + text: "When the last four arguments are omitted, they *must* be assumed to have the values 0, 0, the width member of the imagedata structure, and the height member of the imagedata structure, respectively<^>." + - id: 2d.imageData.put.normal + text: "When invoked with arguments that do not, per the last few paragraphs, cause an exception to be raised, the putImageData() method *must* act as follows<^>:" + + - id: 2d.imageData.unchanged + text: "the following *must* result in no visible changes to the rendering<^>:" + - id: 2d.imageData.createround + text: "...*must* return ImageData objects with the same dimensions, for any value of w and h<^>." + - id: 2d.imageData.unaffected + text: "The current path, transformation matrix, shadow attributes, global alpha, the clipping region, and global composition operator *must* not affect the getImageData() and putImageData() methods<^>." + + - id: 2d.drawingmodel + text: "When a shape or image is painted, user agents *must* follow these steps, in the order given (or act as if they do)<^>:" + + - id: 2d.colorspace.correction + text: "The canvas APIs *must* perform color correction at only two points: when rendering images with their own gamma correction and color space information onto the canvas, to convert the image to the color space used by the canvas (e.g. using the 2D Context's drawImage() method with an HTMLImageElement object)<^>," + - id: 2d.colorspace.toDataURL.info + text: "The toDataURL() method *must* not include color space information in the resource returned<^>." + - id: 2d.colorspace.toDataURL.equal + text: "Where the output format allows it, the color of pixels in resources created by toDataURL() *must* match those returned by the getImageData() method<^>." + - id: 2d.colorspace.match + text: "In user agents that support CSS, the color space used by a canvas element *must* match the color space used for processing any colors for that element in CSS<^>." + - id: 2d.colorspace.img.equal + text: "The gamma correction and color space information of images *must* be handled in such a way that an image rendered directly using an img element would use the same colors as one painted on a canvas element that is then itself rendered<^>." + - id: 2d.colorspace.img.noinfo + text: "Furthermore, the rendering of images that have no color correction information (such as those returned by the toDataURL() method) *must* be rendered with no color correction<^>." + + - id: security.start + text: "All canvas elements *must* start with their origin-clean set to true<^>." + - id: security.drawImage.image + keyword: must + text: "The element's 2D context's drawImage() method is called with an HTMLImageElement or an HTMLVideoElement whose origin is not the same as that of the Document object that owns the canvas element<^>." + - id: security.drawImage.canvas + keyword: must + text: "The element's 2D context's drawImage() method is called with an HTMLCanvasElement whose origin-clean flag is false<^>." + - id: security.fillStyle.image + keyword: must + text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement<^> or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created." + - id: security.fillStyle.video + keyword: must + text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement<^> whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created." + - id: security.fillStyle.canvas + keyword: must + text: "The element's 2D context's fillStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created<^>." + - id: security.strokeStyle.image + keyword: must + text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement<^> or an HTMLVideoElement whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created." + - id: security.strokeStyle.video + keyword: must + text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLImageElement or an HTMLVideoElement<^> whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created." + - id: security.strokeStyle.canvas + keyword: must + text: "The element's 2D context's strokeStyle attribute is set to a CanvasPattern object that was created from an HTMLCanvasElement whose origin-clean flag was false when the pattern was created<^>." + - id: security.toDataURL + text: "Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method *must* raise a SECURITY_ERR exception<^>." + - id: security.getImageData + text: "Whenever the getImageData() method of the 2D context of a canvas element whose origin-clean flag is set to false is called with otherwise correct arguments, the method *must* raise a SECURITY_ERR exception<^>."
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/specextract.py b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/specextract.py new file mode 100644 index 0000000..042c0bd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/specextract.py
@@ -0,0 +1,57 @@ +import html5lib +import html5lib.treebuilders.dom + +# Expected use: +# curl --compressed http://www.whatwg.org/specs/web-apps/current-work/ >current-work +# python specextract.py +# +# Generates current-work-canvas.xhtml, for use by gentest.py to create the annotated spec document + +def extract(): + parser = html5lib.html5parser.HTMLParser(tree=html5lib.treebuilders.dom.TreeBuilder) + doc = parser.parse(open('current-work', "r"), encoding='utf-8') + + head = doc.getElementsByTagName('head')[0] + for n in head.childNodes: + if n.tagName == 'script': + head.removeChild(n) + + header = doc.getElementsByTagName('header')[0] + #thecanvas = doc.getElementById('the-canvas') # doesn't work (?!) + thecanvas = [ n for n in doc.getElementsByTagName('h4') if n.getAttribute('id') == 'the-canvas-element' ][0] + + keep = [header, thecanvas] + node = thecanvas.nextSibling + while node.nodeName != 'h4': + keep.append(node) + node = node.nextSibling + p = thecanvas.parentNode + for n in p.childNodes[:]: + if n not in keep: + p.removeChild(n) + + for n in header.childNodes[3:-4]: + header.removeChild(n) + + def make_absolute(uri): + if uri.startswith('data:'): + return uri + elif uri[0] == '/': + return 'http://www.whatwg.org' + uri + else: + return 'http://www.whatwg.org/specs/web-apps/current-work/' + uri + + # Fix the stylesheet, icon and image references + for e in doc.getElementsByTagName('link'): + e.setAttribute('href', make_absolute(e.getAttribute('href'))) + for img in doc.getElementsByTagName('img'): + img.setAttribute('src', make_absolute(img.getAttribute('src'))) + + # Convert to XHTML, because it's quicker to re-parse than HTML5 + doc.documentElement.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml') + doc.documentElement.setAttribute('xml:lang', doc.documentElement.getAttribute('lang')) + doc.removeChild(doc.firstChild) # remove the DOCTYPE + + open('current-work-canvas.xhtml', 'w').write(doc.toxml(encoding = 'UTF-8')) + +extract()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/templates.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/templates.yaml new file mode 100644 index 0000000..a67f3aa --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/templates.yaml
@@ -0,0 +1,378 @@ +# Copyright (c) 2010 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +framed: | + <!DOCTYPE html> + <title>Canvas test: %(name)s</title> + <script src="../tests.js"></script> + <link rel="stylesheet" href="../tests.css"> + %(fonts)s<body class="framed show_output"> + <h1> + <a href="%(name)s.html" target="_parent">%(name_wrapped)s</a> + </h1> + <p><a href="#" id="show_output" onclick="document.body.className += ' show_output'; return false">[show output]</a> + %(fonthack)s<p class="output">Actual output:</p> + <canvas id="c" class="output" %(canvas)s>%(fallback)s</canvas> + %(expected)s + <ul id="d"></ul> + <script> + _addTest(function(canvas, ctx) { + + %(code)s + + }); + </script> + %(images)s + +standalone: | + <!DOCTYPE html> + <title>Canvas test: %(name)s</title> + <script src="../tests.js"></script> + <link rel="stylesheet" href="../tests.css"> + <link rel="prev" href="%(prev)s.html" title="%(prev)s"> + <link rel="next" href="%(next)s.html" title="%(next)s"> + %(fonts)s<body class="show_output"> + <p> + <a href="%(prev)s.html" accesskey="p" title="[p] %(prev)s"><</a> + <a href="index.html">[index]</a> + <a href="%(next)s.html" accesskey="n" title="[n] %(next)s">></a> + <h1>%(backrefs)s</h1> + <p class="desc">%(desc)s</p> + <div class="refs">References: + <ul> + %(refs)s + </ul> + </div> + %(notes)s + %(fonthack)s<p class="output">Actual output:</p> + <canvas id="c" class="output" %(canvas)s>%(fallback)s</canvas> + %(expected)s + <ul id="d"></ul> + <script> + _addTest(function(canvas, ctx) { + + %(code)s + + }); + </script> + %(images)s + +minimal: | + <!DOCTYPE html> + <html class="minimal"> + <title>Canvas test: %(name)s</title> + <script src="../tests.js"></script> + <link rel="stylesheet" href="../tests.css"> + <link rel="prev" href="minimal.%(prev)s.html" title="%(prev)s"> + <link rel="next" href="minimal.%(next)s.html" title="%(next)s"> + %(fonts)s<body> + <p id="passtext">Pass</p> + <p id="failtext">Fail</p> + <!-- TODO: handle "script did not run" case --> + %(fonthack)s<p class="output">These images should be identical:</p> + <canvas id="c" class="output" %(canvas)s>%(fallback)s</canvas> + %(expected)s + <ul id="d"></ul> + <script> + _addTest(function(canvas, ctx) { + + %(code)s + + }); + </script> + %(images)s + +w3c: | + <!DOCTYPE html> + <!-- DO NOT EDIT! This test has been generated by tools/gentest.py. --> + <title>Canvas test: %(name)s</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/common/canvas-tests.js"></script> + <link rel="stylesheet" href="/common/canvas-tests.css"> + %(fonts)s<body class="show_output"> + + <h1>%(name)s</h1> + <p class="desc">%(desc)s</p> + + %(notes)s + %(fonthack)s<p class="output">Actual output:</p> + <canvas id="c" class="output" %(canvas)s>%(fallback)s</canvas> + %(expected)s + <ul id="d"></ul> + <script> + var t = async_test("%(escaped_desc)s"); + _addTest(function(canvas, ctx) { + + %(code)s + + }); + </script> + %(scripts)s%(images)s + +mochitest: | + <!DOCTYPE HTML> + <title>%(mochi_name_fn)s</title> + %(mochi_desc)s<script src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> + %(fonts)s<body><!-- [[[ test_%(mochi_name)s.html ]]] --> + + <p>Canvas test: %(mochi_name)s</p> + %(mochi_desc)s%(fonthack)s<canvas id="c" %(canvas)s>%(fallback)s</canvas> + <script> + + function %(mochi_name_fn)s() { + + var canvas = document.getElementById('c'); + var ctx = canvas.getContext('2d'); + + %(mochi_code)s + + } + </script> + %(mochi_images)s + +mochitest.isPixel: | + function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) { + var pixel = ctx.getImageData(x, y, 1, 1); + var pr = pixel.data[0], + pg = pixel.data[1], + pb = pixel.data[2], + pa = pixel.data[3]; + ok(r-d <= pr && pr <= r+d && + g-d <= pg && pg <= g+d && + b-d <= pb && pb <= b+d && + a-d <= pa && pa <= a+d, + "pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d); + } + +mochitest.todo_isPixel: | + function todo_isPixel(ctx, x,y, r,g,b,a, pos, colour, d) { + var pixel = ctx.getImageData(x, y, 1, 1); + var pr = pixel.data[0], + pg = pixel.data[1], + pb = pixel.data[2], + pa = pixel.data[3]; + todo(r-d <= pr && pr <= r+d && + g-d <= pg && pg <= g+d && + b-d <= pb && pb <= b+d && + a-d <= pa && pa <= a+d, + "pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d); + } + +mochitest.deferTest: | + function deferTest() { + _deferred = true; + } + +mochitest.wrapFunction: | + function wrapFunction(f) { + return function () { + f.apply(null, arguments); + SimpleTest.finish(); + } + } + +mochitest.exception: | + var _thrown_outer = false; + try { + + %s + } catch (e) { + _thrown_outer = true; + } + todo(!_thrown_outer, 'should not throw exception'); + +mochitest.Makefile: | + # + # ***** BEGIN LICENSE BLOCK ***** + # Version: MPL 1.1/GPL 2.0/LGPL 2.1 + # + # The contents of this file are subject to the Mozilla Public License Version + # 1.1 (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.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS IS" basis, + # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + # for the specific language governing rights and limitations under the + # License. + # + # The Original Code is mozilla.org code. + # + # The Initial Developer of the Original Code is + # Mozilla Corporation. + # Portions created by the Initial Developer are Copyright (C) 2007 + # the Initial Developer. All Rights Reserved. + # + # Contributor(s): + # Philip Taylor <philip.taylor@cl.cam.ac.uk> + # + # Alternatively, the contents of this file may be used under the terms of + # either of the GNU General Public License Version 2 or later (the "GPL"), + # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + # in which case the provisions of the GPL or the LGPL are applicable instead + # of those above. If you wish to allow use of your version of this file only + # under the terms of either the GPL or the LGPL, and not to allow others to + # use your version of this file under the terms of the MPL, indicate your + # decision by deleting the provisions above and replace them with the notice + # and other provisions required by the GPL or the LGPL. If you do not delete + # the provisions above, a recipient may use your version of this file under + # the terms of any one of the MPL, the GPL or the LGPL. + # + # ***** END LICENSE BLOCK ***** + + DEPTH = ../../.. + topsrcdir = @top_srcdir@ + srcdir = @srcdir@ + VPATH = @srcdir@ + relativesrcdir = content/canvas/test + + include $(DEPTH)/config/autoconf.mk + include $(topsrcdir)/config/rules.mk + + +index.frame: | + <!DOCTYPE html> + <title>Canvas tests - %(category)s.*</title> + <link rel="stylesheet" href="../frame.css"> + <p><a href="index.html">[index]</a> + <h1>%(backrefs)s.*</h1> + <p> + +# FF trunk doesn't do onload in object, so use iframe instead +#index.frame.item: |- +# <object width="200" height="220" data="framed.%s.html">(object fallback)</object><!-- +# --> +index.frame.item: |- + <iframe width="200" height="220" src="framed.%s.html">(iframe fallback)</iframe><!-- + --> + +index.w3c.frame: | + <!DOCTYPE html> + <title>Canvas tests - %(category)s.*</title> + <link rel="stylesheet" href="/common/canvas-frame.css"> + <p><a href="index.html">[index]</a> + <h1>%(backrefs)s.*</h1> + <p> + +index.w3c.frame.item: |- + <iframe width="320" height="240" src="%s.html">(iframe fallback)</iframe><!-- + --> + +index: | + <!DOCTYPE html> + <title>Canvas tests - index</title> + <link rel="stylesheet" href="../index.css"> + <script> + function expand(obj) { + obj.parentNode.className = obj.parentNode.className ? "" : "expand"; + return false; + } + </script> + + <h1><code><canvas></code> tests</h1> + + <p>Developed by <a href="mailto:excors@gmail.com">Philip Taylor</a>. + Last updated %(updated)s. + + <p>Based on the <a + href="http://www.whatwg.org/specs/web-apps/current-work/#the-canvas">HTML</a> + Draft Standard — 22 February 2010. See also the <a + href="spec.html">annotated specification</a>. + + <p>See <a href="results.html">test results</a> for some browsers. + (Generated semi-automatically via the <a + href="../reportgenentry.html">report generator</a>.) + + <p>You may want to <a href="../source.tar.bz2">download the source + code/data</a> (e.g. to create an offline copy of the tests). + + <h2>Test cases</h2> + + <p>For each test, a green background indicates success, red indicates + failure, blue indicates a need to manually confirm the output is as + expected. + + <p>The versions in the report generator are the most visually minimalist. + The category links below show the actual and expected renderings, and any + error messages. The individual test pages have links to relevant parts of + the specification and extra notes. + + <p>There may be many inaccuracies: tests that do not notice when part of + the output is incorrect; tests that are too intolerant of acceptable + renderings differences, or make other unreasonable assumptions; tests that + were written for an outdated version of the specification, and tests that + are just wrong. Also a number of features are not tested, most notably text + rendering. Please contact me (<a + href="mailto:excors@gmail.com">email</a>, <a + href="http://wiki.whatwg.org/wiki/IRC">IRC</a>, etc) if you find any + problems. + +index.w3c: | + <!DOCTYPE html> + <title>Canvas tests - index</title> + <link rel="stylesheet" href="/common/canvas-index.css"> + + <h1><code><canvas></code> tests</h1> + +index.category.item: | + <li><h3><a href="index.%s.html">%s.*</a></h3><p>%d test%s <a href="#" onclick="return expand(this)">expand</a></p> + +index.w3c.category.item: | + <li><h3><a href="index.%s.html">%s.*</a></h3><p>%d test%s</p> + +reportgen: | + <!DOCTYPE html> + <title>Canvas tests - report generator</title> + <link rel="stylesheet" href="../reportgen.css"> + <script src="../reportgen.js"></script> + <p>This is mainly for my own use, so it is not designed to be user-friendly. + If anyone else wants to use it for some reason, just wait + until "tests not yet loaded" and "tests not yet completed" get down to zero, then click the + pass/fail button for any test it shows where it cannot work out the answer (or use the + <kbd>y</kbd>/<kbd>n</kbd> keys to choose for the magenta-highlighted case), then use the + buttons at the bottom to collect all the results. + <form id="f"> + <p><label for="loading">Tests not yet loaded:</label> <input id="loading" value="0" readonly> + <p><label for="waiting">Tests not yet completed:</label> <input id="waiting" value="0" readonly> + <p><button type="button" onclick="showUnfinished()">Show uncompleted tests</button> + <button type="button" onclick="showAll()">Show all tests</button> + <button type="button" onclick="reloadAll()">Reload test cases serially</button> + <!--<button type="button" onclick="avoidFrameLimit()">HACK: work around frame limit</button> + <button type="button" onclick="makeObjects()">HACK: s/iframe/object/</button>--> + <hr> + <p><label for="passed">Detected passes:</label> <input id="passed" value="0" readonly> + <p><label for="failed">Detected fails:</label> <input id="failed" value="0" readonly> + <hr> + <table> + <tr> + <th>Test name + <th>Test case + <th>Pass? + <th>Fail? + <th>Notes + <script> + createTable( [ + %(items)s + ] ); + </script> + </table> + </form> + <hr> + <form method="post" action="../submitresults.cgi"> + <button type="button" onclick="document.getElementById('report').value = genreport()">Generate test report</button><br> + <textarea name="report" id="report" cols="100" rows="10"></textarea><br> + <input type="submit" value="Submit results"> (Submissions will tend to be ignored unless there + is a good reason why they won't be, so don't use this form unless there is such a reason.) + </form> + +results: | + <!DOCTYPE html> + <title>Canvas tests - results</title> + <link rel="stylesheet" href="../results.css"> + <table> + <col id="col1"> + <tr> + <th>Test
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests.yaml new file mode 100644 index 0000000..30ce6551 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests.yaml
@@ -0,0 +1,1054 @@ +# Copyright (c) 2010 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +- name: fallback.basic + desc: Fallback content is inserted into the DOM + testing: + - fallback + code: | + @assert canvas.childNodes.length === 1; + +- name: fallback.multiple + desc: Fallback content with multiple elements + testing: + - fallback + fallback: '<p class="fallback">FAIL</p><p class="fallback">FAIL</p>' + code: | + @assert canvas.childNodes.length === 2; + +- name: fallback.nested + desc: Fallback content containing another canvas (mostly testing parsers) + testing: + - fallback + fallback: '<canvas><p class="fallback">FAIL (fallback content)</p></canvas><p class="fallback">FAIL (fallback content)</p>' + code: | + @assert canvas.childNodes.length === 2; + +- name: type.name + desc: HTMLCanvasElement type and toString + testing: + - canvas.type + code: | + @assert Object.prototype.toString.call(canvas) === '[object HTMLCanvasElement]'; + +- name: type.exists + desc: HTMLCanvasElement is a property of window + notes: &bindings Defined in "Web IDL" (draft) + testing: + - canvas.type + code: | + @assert window.HTMLCanvasElement; + +- name: type.delete + desc: window.HTMLCanvasElement interface object is [[Configurable]] + notes: *bindings + testing: + - canvas.type + code: | + @assert delete window.HTMLCanvasElement === true; + @assert window.HTMLCanvasElement === undefined; + +- name: type.prototype + desc: window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not + notes: *bindings + testing: + - canvas.type + code: | + @assert window.HTMLCanvasElement.prototype; + @assert window.HTMLCanvasElement.prototype.getContext; + window.HTMLCanvasElement.prototype = null; + @assert window.HTMLCanvasElement.prototype; + delete window.HTMLCanvasElement.prototype; + @assert window.HTMLCanvasElement.prototype; + window.HTMLCanvasElement.prototype.getContext = 1; + @assert window.HTMLCanvasElement.prototype.getContext === 1; + delete window.HTMLCanvasElement.prototype.getContext; + @assert window.HTMLCanvasElement.prototype.getContext === undefined; + +- name: type.replace + desc: HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases + notes: *bindings + testing: + - canvas.type + code: | + window.HTMLCanvasElement.prototype.getContext = function (name) { return 0; }; + @assert canvas.getContext('2d') === 0; + +- name: type.extend + desc: HTMLCanvasElement methods can be added, and the new methods used by canvases + notes: *bindings + testing: + - canvas.type + code: | + window.HTMLCanvasElement.prototype.getZero = function () { return 0; }; + @assert canvas.getZero() === 0; + + +- name: size.attributes.idl.set.zero + desc: Setting width/height IDL attributes to 0 + testing: + - size.width + - size.height + code: | + canvas.width = 0; + canvas.height = 0; + @assert canvas.width === 0; + @assert canvas.height === 0; +# expected: size 0 0 # can't generate zero-sized PNG + +- name: size.attributes.idl + desc: Getting/setting width/height IDL attributes + testing: + - size.width + - size.height + webidl: + - es-unsigned-long + code: | + canvas.width = "100"; + canvas.height = "100"; + @assert canvas.width === 100; + @assert canvas.height === 100; + + canvas.width = "+1.5e2"; + canvas.height = "0x96"; + @assert canvas.width === 150; + @assert canvas.height === 150; + + canvas.width = 200 - Math.pow(2, 32); + canvas.height = 200 - Math.pow(2, 32); + @assert canvas.width === 200; + @assert canvas.height === 200; + + canvas.width = 301.999; + canvas.height = 301.001; + @assert canvas.width === 301; + @assert canvas.height === 301; + + canvas.width = "400x"; + canvas.height = "foo"; + @assert canvas.width === 0; + @assert canvas.height === 0; + +- name: size.attributes.default + desc: Default width/height when attributes are missing + testing: + - size.default + - size.missing + canvas: "" + code: | + @assert canvas.width === 300; + @assert canvas.height === 150; + @assert !canvas.hasAttribute('width'); + @assert !canvas.hasAttribute('height'); + expected: size 300 150 + +- name: size.attributes.reflect.setidl + desc: Setting IDL attributes updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.width = 120; + canvas.height = 60; + @assert canvas.getAttribute('width') === '120'; + @assert canvas.getAttribute('height') === '60'; + @assert canvas.width === 120; + @assert canvas.height === 60; + expected: size 120 60 + +- name: size.attributes.reflect.setidlzero + desc: Setting IDL attributes to 0 updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.width = 0; + canvas.height = 0; + @assert canvas.getAttribute('width') === '0'; + @assert canvas.getAttribute('height') === '0'; + @assert canvas.width === 0; + @assert canvas.height === 0; +# expected: size 0 0 # can't generate zero-sized PNG + +- name: size.attributes.reflect.setcontent + desc: Setting content attributes updates IDL and content attributes + testing: + - size.reflect + code: | + canvas.setAttribute('width', '120'); + canvas.setAttribute('height', '60'); + @assert canvas.getAttribute('width') === '120'; + @assert canvas.getAttribute('height') === '60'; + @assert canvas.width === 120; + @assert canvas.height === 60; + expected: size 120 60 + +- name: size.attributes.removed + desc: Removing content attributes reverts to default size + testing: + - size.missing + canvas: width="120" height="60" + code: | + @assert canvas.width === 120; + canvas.removeAttribute('width'); + @assert canvas.width === 300; + expected: size 300 60 + +- meta: | + cases = [ + ("zero", "0", 0), + ("empty", "", None), + ("onlyspace", " ", None), + ("space", " 100", 100), + ("whitespace", "\n\t\f100", 100), + ("plus", "+100", 100), + ("minus", "-100", None), + ("octal", "0100", 100), + ("hex", "0x100", 0), + ("exp", "100e1", 100), + ("decimal", "100.999", 100), + ("percent", "100%", 100), + ("em", "100em", 100), + ("junk", "#!?", None), + ("trailingjunk", "100#!?", 100), + ] + def gen(name, string, exp, code): + testing = ["size.nonnegativeinteger"] + if exp is None: + testing.append("size.error") + code += "@assert canvas.width === 300;\n@assert canvas.height === 150;\n" + expected = "size 300 150" + else: + code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp) + expected = "size %s %s" % (exp, exp) + + # With "100%", Opera gets canvas.width = 100 but renders at 100% of the frame width, + # so check the CSS display width + code += '@assert window.getComputedStyle(canvas, null).getPropertyValue("width") === "%spx";\n' % (exp, ) + + code += "@assert canvas.getAttribute('width') === %r;\n" % string + code += "@assert canvas.getAttribute('height') === %r;\n" % string + + if exp == 0: + expected = None # can't generate zero-sized PNGs for the expected image + + return code, testing, expected + + for name, string, exp in cases: + code = "" + code, testing, expected = gen(name, string, exp, code) + tests.append( { + "name": "size.attributes.parse.%s" % name, + "desc": "Parsing of non-negative integers", + "testing": testing, + "canvas": 'width="%s" height="%s"' % (string, string), + "code": code, + "expected": expected + } ) + + for name, string, exp in cases: + code = "canvas.setAttribute('width', %r);\ncanvas.setAttribute('height', %r);\n" % (string, string) + code, testing, expected = gen(name, string, exp, code) + tests.append( { + "name": "size.attributes.setAttribute.%s" % name, + "desc": "Parsing of non-negative integers in setAttribute", + "testing": testing, + "canvas": 'width="50" height="50"', + "code": code, + "expected": expected + } ) + +- name: size.attributes.style + desc: Canvas size is independent of CSS resizing + testing: + - size.css + canvas: 'width="50" height="30" style="width: 100px; height: 50px"' + code: | + @assert canvas.width === 50; + @assert canvas.height === 30; + expected: size 100 50 + +- name: size.large + DISABLED: | + "User agents may impose implementation-specific limits on otherwise unconstrained + inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, + or to work around platform-specific limitations." + testing: + - size.width + - size.height + notes: Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size. + code: | + var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long" + canvas.width = n; + canvas.height = n; + @assert canvas.width === n; + @assert canvas.height === n; +# expected: size 2147483647 2147483647 # not a good idea to generate the expected image in this case... + +- name: initial.colour + desc: Initial state is transparent black + testing: + - initial.colour + notes: | + Output should be transparent black (not transparent anything-else), but manual + verification can only confirm that it's transparent - it's not possible to make + the actual blackness visible. + code: | + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.different + desc: Changing size resets canvas to transparent black + testing: + - initial.reset + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + canvas.width = 50; + @assert pixel 20,20 == 0,0,0,0; + expected: size 50 50 # transparent + +- name: initial.reset.same + desc: Setting size (not changing the value) resets canvas to transparent black + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + canvas.width = 100; + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.path + desc: Resetting the canvas state resets the current path + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.rect(0, 0, 100, 50); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 20,20 == 0,0,0,0; + expected: size 100 50 # transparent + +- name: initial.reset.clip + desc: Resetting the canvas state resets the current clip region + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.rect(0, 0, 1, 1); + ctx.clip(); + canvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + expected: green + +- name: initial.reset.transform + desc: Resetting the canvas state resets the current transformation matrix + testing: + - initial.reset + code: | + canvas.width = 100; + ctx.scale(0.1, 0.1); + canvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + expected: green + +- name: initial.reset.gradient + desc: Resetting the canvas state does not invalidate any existing gradients + testing: + - initial.reset + code: | + canvas.width = 50; + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: initial.reset.pattern + desc: Resetting the canvas state does not invalidate any existing patterns + testing: + - initial.reset + code: | + canvas.width = 30; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 30, 50); + var p = ctx.createPattern(canvas, 'repeat-x'); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +# See tests2d.yaml for initial.reset.2dstate + + +- name: context.emptystring + desc: getContext with empty string returns null + testing: + - context.unrecognised + code: | + @assert canvas.getContext("") === null; + +- name: context.unrecognised.badname + desc: getContext with unrecognised context name returns null + testing: + - context.unrecognised + code: | + @assert canvas.getContext('This is not an implemented context in any real browser') === null; + +- name: context.unrecognised.badsuffix + desc: Context name "2d" plus a suffix is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2d#") === null; + +- name: context.unrecognised.nullsuffix + desc: Context name "2d" plus a "\0" suffix is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2d\0") === null; + +- name: context.unrecognised.unicode + desc: Context name which kind of looks like "2d" is unrecognised + testing: + - context.unrecognised + code: | + @assert canvas.getContext("2\uFF44") === null; // Fullwidth Latin Small Letter D + +- name: context.casesensitive + desc: Context name "2D" is unrecognised; matching is case sensitive + testing: + - context.unrecognised + code: | + @assert canvas.getContext('2D') === null; + +- name: context.arguments.missing + notes: *bindings + testing: + - canvas.getContext + code: | + @assert throws TypeError canvas.getContext(); @moz-todo + + + +- name: toDataURL.default + desc: toDataURL with no arguments returns a PNG + testing: + - toDataURL.noarguments + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.png + desc: toDataURL with image/png returns a PNG + testing: + - toDataURL.png + - toDataURL.witharguments + code: | + var data = canvas.toDataURL('image/png'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.jpg + desc: toDataURL with image/jpg is invalid type hence returns a PNG + testing: + - toDataURL.jpg + - toDataURL.witharguments + code: | + var data = canvas.toDataURL('image/jpg'); + @assert data =~ /^data:image\/png[;,]/; + + +- name: toDataURL.bogustype + desc: toDataURL with a syntactically invalid type returns a PNG + testing: + - toDataURL.unrecognised + code: | + var data = canvas.toDataURL('bogus'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.unrecognised + desc: toDataURL with an unhandled type returns a PNG + testing: + - toDataURL.unrecognised + code: | + var data = canvas.toDataURL('image/example'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.lowercase.ascii + desc: toDataURL type is case-insensitive + testing: + - toDataURL.lowercase + code: | + var data = canvas.toDataURL('ImAgE/PnG'); + @assert data =~ /^data:image\/png[;,]/; + + // If JPEG is supported at all, it must be supported case-insensitively + data = canvas.toDataURL('image/jpeg'); + if (data.match(/^data:image\/jpeg[;,]/)) { + data = canvas.toDataURL('ImAgE/JpEg'); + @assert data =~ /^data:image\/jpeg[;,]/; + } + +- name: toDataURL.lowercase.unicode + desc: toDataURL type is ASCII-case-insensitive + testing: + - toDataURL.lowercase + code: | + // Use LATIN CAPITAL LETTER I WITH DOT ABOVE (Unicode lowercase is "i") + var data = canvas.toDataURL('\u0130mage/png'); + @assert data =~ /^data:image\/png[;,]/; + + var data = canvas.toDataURL('\u0130mage/jpeg'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.1 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.2 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception', 'and another'); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.arguments.3 + desc: toDataURL ignores extra arguments + testing: + - toDataURL.arguments + code: | + // More arguments that should not raise exceptions + var data = canvas.toDataURL('image/png', null, null, null); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.nocontext + desc: toDataURL works before any context has been got + testing: + - toDataURL.noarguments + code: | + var no_context_data = canvas.toDataURL(); + var ctx = canvas.getContext('2d'); + ctx.rect(0, 0, 100, 50); + ctx.fillStyle = "rgba(0, 0, 0, 0)"; + ctx.fill(); + var data = canvas.toDataURL(); + assert_equals(no_context_data, data); + +- name: toDataURL.zerosize + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: width="0" height="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.zerowidth + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: width="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.zeroheight + desc: toDataURL on zero-size canvas returns 'data:,' + testing: + - toDataURL.zerosize + canvas: height="0" + code: | + var data = canvas.toDataURL(); + @assert data === 'data:,'; + +- name: toDataURL.large1 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="30000" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.large2 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="32767" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.large3 + DISABLED: just testing implementation limits, and tends to crash + canvas: width="32768" height="1" + code: | + var data = canvas.toDataURL(); + @assert data =~ /^data:image\/png[;,]/; + +- name: toDataURL.png.primarycolours + desc: toDataURL with PNG handles simple colours correctly + testing: + - toDataURL.png + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 25, 40); + ctx.fillStyle = '#0ff'; + ctx.fillRect(25, 0, 50, 40); + ctx.fillStyle = '#00f'; + ctx.fillRect(75, 0, 25, 40); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 40, 100, 10); + var data = canvas.toDataURL(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 12,20 == 255,255,0,255; + @assert pixel 50,20 == 0,255,255,255; + @assert pixel 87,20 == 0,0,255,255; + @assert pixel 50,45 == 255,255,255,255; + }); + img.src = data; + expected: | + size 100 50 + cr.set_source_rgb(1, 1, 0) + cr.rectangle(0, 0, 25, 40) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(25, 0, 50, 40) + cr.fill() + cr.set_source_rgb(0, 0, 1) + cr.rectangle(75, 0, 25, 40) + cr.fill() + cr.set_source_rgb(1, 1, 1) + cr.rectangle(0, 40, 100, 10) + cr.fill() + +- name: toDataURL.png.complexcolours + desc: toDataURL with PNG handles non-primary and non-solid colours correctly + testing: + - toDataURL.png + code: | + // (These values are chosen to survive relatively alright through being premultiplied) + ctx.fillStyle = 'rgba(1, 3, 254, 1)'; + ctx.fillRect(0, 0, 25, 25); + ctx.fillStyle = 'rgba(8, 252, 248, 0.75)'; + ctx.fillRect(25, 0, 25, 25); + ctx.fillStyle = 'rgba(6, 10, 250, 0.502)'; + ctx.fillRect(50, 0, 25, 25); + ctx.fillStyle = 'rgba(12, 16, 244, 0.25)'; + ctx.fillRect(75, 0, 25, 25); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 25); + // (The alpha values do not really survive float->int conversion, so just + // do approximate comparisons) + @assert pixel 12,40 == 1,3,254,255; + @assert pixel 37,40 ==~ 8,252,248,191 +/- 2; + @assert pixel 62,40 ==~ 6,10,250,127 +/- 4; + @assert pixel 87,40 ==~ 12,16,244,63 +/- 8; + }); + img.src = canvas.toDataURL(); + expected: | + size 100 50 + cr.set_source_rgba(1/255., 3/255., 254/255., 1) + cr.rectangle(0, 0, 25, 50) + cr.fill() + cr.set_source_rgba(8/255., 252/255., 248/255., 191/255.) + cr.rectangle(25, 0, 25, 50) + cr.fill() + cr.set_source_rgba(6/255., 10/255., 250/255., 127/255.) + cr.rectangle(50, 0, 25, 50) + cr.fill() + cr.set_source_rgba(12/255., 16/255., 244/255., 63/255.) + cr.rectangle(75, 0, 25, 50) + cr.fill() + +- name: toDataURL.jpeg.primarycolours + desc: toDataURL with JPEG handles simple colours correctly + testing: + - toDataURL.jpeg + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 25, 40); + ctx.fillStyle = '#0ff'; + ctx.fillRect(25, 0, 50, 40); + ctx.fillStyle = '#00f'; + ctx.fillRect(75, 0, 25, 40); + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 40, 100, 10); + var data = canvas.toDataURL('image/jpeg'); // it is okay if this returns a PNG instead + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 12,20 ==~ 255,255,0,255 +/- 8; + @assert pixel 50,20 ==~ 0,255,255,255 +/- 8; + @assert pixel 87,20 ==~ 0,0,255,255 +/- 8; + @assert pixel 50,45 ==~ 255,255,255,255 +/- 8; + }); + img.src = data; + expected: | + size 100 50 + cr.set_source_rgb(1, 1, 0) + cr.rectangle(0, 0, 25, 40) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(25, 0, 50, 40) + cr.fill() + cr.set_source_rgb(0, 0, 1) + cr.rectangle(75, 0, 25, 40) + cr.fill() + cr.set_source_rgb(1, 1, 1) + cr.rectangle(0, 40, 100, 10) + cr.fill() + +- name: toDataURL.jpeg.alpha + desc: toDataURL with JPEG composites onto black + testing: + - toDataURL.jpeg + - toDataURL.noalpha + code: | + ctx.fillStyle = 'rgba(128, 255, 128, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; // should be ignored by toDataURL + var data = canvas.toDataURL('image/jpeg'); + ctx.globalCompositeOperation = 'source-over'; + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 63,127,63,255 +/- 8; + }); + img.src = data; + } + expected: | + size 100 50 + cr.set_source_rgb(0.25, 0.5, 0.25) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: toDataURL.jpeg.quality.basic + desc: toDataURL with JPEG uses the quality parameter + testing: + - toDataURL.jpeg.quality + mozilla: { throws } + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + var data_hi = canvas.toDataURL('image/jpeg', 0.99); + var data_lo = canvas.toDataURL('image/jpeg', 0.01); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + deferTest(); + var img_hi = new Image(); + img_hi.onload = function () + { + var img_lo = new Image(); + img_lo.onload = t.step_func_done(function () + { + ctx.drawImage(img_hi, 0, 0, 50, 50, 0, 0, 50, 50); + ctx.drawImage(img_lo, 0, 0, 50, 50, 50, 0, 50, 50); + @assert data_hi.length > data_lo.length; + @assert pixel 25,25 ==~ 0,0,255,255 +/- 8; + @assert pixel 75,25 ==~ 0,0,255,255 +/- 32; + }); + img_lo.src = data_lo; + }; + img_hi.src = data_hi; + } + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 1) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(0, 3, 100, 1) + cr.fill() + +- name: toDataURL.jpeg.quality.notnumber + desc: toDataURL with JPEG handles non-numeric quality parameters + testing: + - toDataURL.jpeg.nan + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + @assert canvas.toDataURL('image/jpeg', 'bogus') === data; + @assert canvas.toDataURL('image/jpeg', {}) === data; + @assert canvas.toDataURL('image/jpeg', null) === data; + @assert canvas.toDataURL('image/jpeg', undefined) === data; + @assert canvas.toDataURL('image/jpeg', true) === data; + @assert canvas.toDataURL('image/jpeg', '0.01') === data; + } + +- name: toDataURL.jpeg.quality.outsiderange + desc: toDataURL with JPEG handles out-of-range quality parameters + testing: + - toDataURL.jpeg.range + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 3, 100, 1); + // Check for JPEG support first + var data = canvas.toDataURL('image/jpeg'); + if (!data.match(/^data:image\/jpeg[;,]/)) { + @assert true; + } else { + @assert canvas.toDataURL('image/jpeg', 10) === data; + @assert canvas.toDataURL('image/jpeg', -10) === data; + @assert canvas.toDataURL('image/jpeg', 1.01) === data; + @assert canvas.toDataURL('image/jpeg', -0.01) === data; + + @assert canvas.toDataURL('image/jpeg', 1).length >= canvas.toDataURL('image/jpeg', 0.9).length; + @assert canvas.toDataURL('image/jpeg', 0).length <= canvas.toDataURL('image/jpeg', 0.1).length; + } + + +# TODO: work out what security exception should be thrown +# TODO: test same-origin vs same-host + +- name: security.drawImage.image + desc: drawImage of different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.drawImage.image + - security.toDataURL + - security.getImageData + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + ctx.drawImage(document.getElementById('yellow.png'), 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.drawImage.canvas + desc: drawImage of unclean canvas makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.drawImage.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + ctx.drawImage(canvas2, 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.create + desc: Creating an unclean pattern does not make the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.start + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + canvas.toDataURL(); + ctx.getImageData(0, 0, 1, 1); + @assert true; // okay if there was no exception + +- name: security.pattern.cross + desc: Using an unclean pattern makes the target canvas origin-unclean, not the pattern canvas + mozilla: { disabled } # relies on external resources + testing: + - security.start + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + var p = ctx2.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + canvas2.toDataURL(); + ctx2.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.timing + desc: Pattern safety depends on whether the source was origin-clean, not on whether it still is clean + notes: Disagrees with spec on "is" vs "was" + mozilla: { disabled } # relies on external resources + testing: + - security.start + - security.fillStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); // make canvas2 origin-unclean + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + canvas.toDataURL(); + ctx.getImageData(0, 0, 1, 1); + @assert true; // okay if there was no exception + +- name: security.pattern.image.fillStyle + desc: Setting fillStyle to a pattern of a different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.fillStyle.image + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.fillStyle = p; + ctx.fillStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.fillStyle + desc: Setting fillStyle to a pattern of an unclean canvas makes the canvas origin-unclean + mozilla: { bug: 354127, disabled } # relies on external resources + testing: + - security.fillStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx.fillStyle = p; + ctx.fillStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.image.strokeStyle + desc: Setting strokeStyle to a pattern of a different-origin image makes the canvas origin-unclean + mozilla: { disabled } # relies on external resources + testing: + - security.strokeStyle.image + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat'); + ctx.strokeStyle = p; + ctx.strokeStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.pattern.canvas.strokeStyle + desc: Setting strokeStyle to a pattern of an unclean canvas makes the canvas origin-unclean + mozilla: { bug: 354127, disabled } # relies on external resources + testing: + - security.strokeStyle.canvas + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); + var p = ctx.createPattern(canvas2, 'repeat'); + ctx.strokeStyle = p; + ctx.strokeStyle = 'red'; + @assert throws SECURITY_ERR canvas.toDataURL(); + @assert throws SECURITY_ERR ctx.getImageData(0, 0, 1, 1); + +- name: security.dataURI + desc: 'data: URIs do not count as different-origin, and do not taint the canvas' + mozilla: { disabled, bug: 417836 } # can't do "todo" so just disable it + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var data = canvas.toDataURL(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.drawImage(img, 0, 0); + canvas.toDataURL(); // should be permitted + @assert pixel 50,25 == 0,255,0,255; + }); + img.src = data; + expected: green + +- name: security.reset + desc: Resetting the canvas state does not reset the origin-clean flag + mozilla: { disabled } # relies on external resources + testing: + - initial.reset + scripts: + - /common/get-host-info.sub.js + - data:text/javascript,addCrossOriginYellowImage() + code: | + canvas.width = 50; + ctx.drawImage(document.getElementById('yellow.png'), 0, 0); + @assert throws SECURITY_ERR canvas.toDataURL(); + canvas.width = 100; + @assert throws SECURITY_ERR canvas.toDataURL();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2d.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2d.yaml new file mode 100644 index 0000000..caae293 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2d.yaml
@@ -0,0 +1,10150 @@ +# Copyright (c) 2011 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +- name: 2d.getcontext.exists + desc: The 2D context is implemented + testing: + - context.2d + code: | + @assert canvas.getContext('2d') !== null; + +- name: 2d.getcontext.extraargs + desc: The 2D context ignores extra getContext arguments + testing: + - context.2d.extraargs + code: | + @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null; + +- name: 2d.type.exists + desc: The 2D context interface is a property of 'window' + notes: &bindings Defined in "Web IDL" (draft) + testing: + - context.2d.type + code: | + @assert window.CanvasRenderingContext2D; + +- name: 2d.type.delete + desc: window.CanvasRenderingContext2D is Configurable + notes: *bindings + testing: + - context.2d.type + code: | + @assert window.CanvasRenderingContext2D !== undefined; + @assert delete window.CanvasRenderingContext2D === true; + @assert window.CanvasRenderingContext2D === undefined; + +- name: 2d.type.prototype + desc: window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]]. + notes: *bindings + testing: + - context.2d.type + code: | + @assert window.CanvasRenderingContext2D.prototype; + @assert window.CanvasRenderingContext2D.prototype.fill; + window.CanvasRenderingContext2D.prototype = null; + @assert window.CanvasRenderingContext2D.prototype; + delete window.CanvasRenderingContext2D.prototype; + @assert window.CanvasRenderingContext2D.prototype; + window.CanvasRenderingContext2D.prototype.fill = 1; + @assert window.CanvasRenderingContext2D.prototype.fill === 1; + delete window.CanvasRenderingContext2D.prototype.fill; + @assert window.CanvasRenderingContext2D.prototype.fill === undefined; + +- name: 2d.type.replace + desc: Interface methods can be overridden + notes: *bindings + testing: + - context.2d.type + code: | + var fillRect = window.CanvasRenderingContext2D.prototype.fillRect; + window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h) + { + this.fillStyle = '#0f0'; + fillRect.call(this, x, y, w, h); + }; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.type.extend + desc: Interface methods can be added + notes: *bindings + testing: + - context.2d.type + code: | + window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h) + { + this.fillStyle = '#0f0'; + this.fillRect(x, y, w, h); + }; + ctx.fillStyle = '#f00'; + ctx.fillRectGreen(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.getcontext.unique + desc: getContext('2d') returns the same object + testing: + - context.unique + code: | + @assert canvas.getContext('2d') === canvas.getContext('2d'); + +- name: 2d.getcontext.shared + desc: getContext('2d') returns objects which share canvas state + testing: + - context.unique + code: | + var ctx2 = canvas.getContext('2d'); + ctx.fillStyle = '#f00'; + ctx2.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.voidreturn + desc: void methods return undefined + notes: *bindings + images: + - yellow.png + code: | + @assert ctx.save() === undefined; + @assert ctx.restore() === undefined; + @assert ctx.scale(1, 1) === undefined; + @assert ctx.rotate(0) === undefined; + @assert ctx.translate(0, 0) === undefined; + if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported) + @assert ctx.transform(1, 0, 0, 1, 0, 0) === undefined; + } + if (ctx.setTransform) { + @assert ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined; + } + @assert ctx.clearRect(0, 0, 0, 0) === undefined; + @assert ctx.fillRect(0, 0, 0, 0) === undefined; + @assert ctx.strokeRect(0, 0, 0, 0) === undefined; + @assert ctx.beginPath() === undefined; + @assert ctx.closePath() === undefined; + @assert ctx.moveTo(0, 0) === undefined; + @assert ctx.lineTo(0, 0) === undefined; + @assert ctx.quadraticCurveTo(0, 0, 0, 0) === undefined; + @assert ctx.bezierCurveTo(0, 0, 0, 0, 0, 0) === undefined; + @assert ctx.arcTo(0, 0, 0, 0, 1) === undefined; + @assert ctx.rect(0, 0, 0, 0) === undefined; + @assert ctx.arc(0, 0, 1, 0, 0, true) === undefined; + @assert ctx.fill() === undefined; + @assert ctx.stroke() === undefined; + @assert ctx.clip() === undefined; + if (ctx.fillText) { + @assert ctx.fillText('test', 0, 0) === undefined; + @assert ctx.strokeText('test', 0, 0) === undefined; + } + if (ctx.putImageData) { + @assert ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0) === undefined; + } + @assert ctx.drawImage(document.getElementById('yellow.png'), 0, 0, 1, 1, 0, 0, 0, 0) === undefined; + @assert ctx.drawImage(canvas, 0, 0, 1, 1, 0, 0, 0, 0) === undefined; + @assert ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white') === undefined; + +- name: 2d.missingargs + desc: Missing arguments cause TypeError + code: | + @assert throws TypeError ctx.scale(); + @assert throws TypeError ctx.scale(1); + @assert throws TypeError ctx.rotate(); + @assert throws TypeError ctx.translate(); + @assert throws TypeError ctx.translate(0); + if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported) + @assert throws TypeError ctx.transform(); + @assert throws TypeError ctx.transform(1); + @assert throws TypeError ctx.transform(1, 0); + @assert throws TypeError ctx.transform(1, 0, 0); + @assert throws TypeError ctx.transform(1, 0, 0, 1); + @assert throws TypeError ctx.transform(1, 0, 0, 1, 0); + } + if (ctx.setTransform) { + @assert throws TypeError ctx.setTransform(); + @assert throws TypeError ctx.setTransform(1); + @assert throws TypeError ctx.setTransform(1, 0); + @assert throws TypeError ctx.setTransform(1, 0, 0); + @assert throws TypeError ctx.setTransform(1, 0, 0, 1); + @assert throws TypeError ctx.setTransform(1, 0, 0, 1, 0); + } + @assert throws TypeError ctx.createLinearGradient(); + @assert throws TypeError ctx.createLinearGradient(0); + @assert throws TypeError ctx.createLinearGradient(0, 0); + @assert throws TypeError ctx.createLinearGradient(0, 0, 1); + @assert throws TypeError ctx.createRadialGradient(); + @assert throws TypeError ctx.createRadialGradient(0); + @assert throws TypeError ctx.createRadialGradient(0, 0); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0, 0); + @assert throws TypeError ctx.createPattern(canvas); + @assert throws TypeError ctx.clearRect(); + @assert throws TypeError ctx.clearRect(0); + @assert throws TypeError ctx.clearRect(0, 0); + @assert throws TypeError ctx.clearRect(0, 0, 0); + @assert throws TypeError ctx.fillRect(); + @assert throws TypeError ctx.fillRect(0); + @assert throws TypeError ctx.fillRect(0, 0); + @assert throws TypeError ctx.fillRect(0, 0, 0); + @assert throws TypeError ctx.strokeRect(); + @assert throws TypeError ctx.strokeRect(0); + @assert throws TypeError ctx.strokeRect(0, 0); + @assert throws TypeError ctx.strokeRect(0, 0, 0); + @assert throws TypeError ctx.moveTo(); + @assert throws TypeError ctx.moveTo(0); + @assert throws TypeError ctx.lineTo(); + @assert throws TypeError ctx.lineTo(0); + @assert throws TypeError ctx.quadraticCurveTo(); + @assert throws TypeError ctx.quadraticCurveTo(0); + @assert throws TypeError ctx.quadraticCurveTo(0, 0); + @assert throws TypeError ctx.quadraticCurveTo(0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(); + @assert throws TypeError ctx.bezierCurveTo(0); + @assert throws TypeError ctx.bezierCurveTo(0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0, 0); + @assert throws TypeError ctx.arcTo(); + @assert throws TypeError ctx.arcTo(0); + @assert throws TypeError ctx.arcTo(0, 0); + @assert throws TypeError ctx.arcTo(0, 0, 0); + @assert throws TypeError ctx.arcTo(0, 0, 0, 0); + @assert throws TypeError ctx.rect(); + @assert throws TypeError ctx.rect(0); + @assert throws TypeError ctx.rect(0, 0); + @assert throws TypeError ctx.rect(0, 0, 0); + @assert throws TypeError ctx.arc(); + @assert throws TypeError ctx.arc(0); + @assert throws TypeError ctx.arc(0, 0); + @assert throws TypeError ctx.arc(0, 0, 1); + @assert throws TypeError ctx.arc(0, 0, 1, 0); + // (6th argument to arc is optional) + if (ctx.isPointInPath) { + @assert throws TypeError ctx.isPointInPath(); + @assert throws TypeError ctx.isPointInPath(0); + } + if (ctx.drawFocusRing) { + @assert throws TypeError ctx.drawFocusRing(); + @assert throws TypeError ctx.drawFocusRing(canvas); + @assert throws TypeError ctx.drawFocusRing(canvas, 0); + } + if (ctx.fillText) { + @assert throws TypeError ctx.fillText(); + @assert throws TypeError ctx.fillText('test'); + @assert throws TypeError ctx.fillText('test', 0); + @assert throws TypeError ctx.strokeText(); + @assert throws TypeError ctx.strokeText('test'); + @assert throws TypeError ctx.strokeText('test', 0); + @assert throws TypeError ctx.measureText(); + } + @assert throws TypeError ctx.drawImage(); + @assert throws TypeError ctx.drawImage(canvas); + @assert throws TypeError ctx.drawImage(canvas, 0); + // TODO: n >= 3 args on drawImage could be either a valid overload, + // or too few for another overload, or too many for another + // overload - what should happen? + if (ctx.createImageData) { + @assert throws TypeError ctx.createImageData(); + @assert throws TypeError ctx.createImageData(1); + } + if (ctx.getImageData) { + @assert throws TypeError ctx.getImageData(); + @assert throws TypeError ctx.getImageData(0); + @assert throws TypeError ctx.getImageData(0, 0); + @assert throws TypeError ctx.getImageData(0, 0, 1); + } + if (ctx.putImageData) { + var imgdata = ctx.getImageData(0, 0, 1, 1); + @assert throws TypeError ctx.putImageData(); + @assert throws TypeError ctx.putImageData(imgdata); + @assert throws TypeError ctx.putImageData(imgdata, 0); + } + var g = ctx.createLinearGradient(0, 0, 0, 0); + @assert throws TypeError g.addColorStop(); @moz-todo + @assert throws TypeError g.addColorStop(0); @moz-todo + +- name: 2d.coordinatespace + desc: Coordinate space goes from top-left to bottom-right + notes: This should not be upside down. + manual: We can't tell that getPixelData isn't using the wrong coordinate space too. + testing: + - 2d.coordinatespace + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 25,12 == 0,255,255,255; + @assert pixel 75,12 == 0,0,255,255; + @assert pixel 25,37 == 0,0,255,255; + @assert pixel 75,37 == 0,0,255,255; + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 1) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(0, 0, 50, 25) + cr.fill() + +- name: 2d.scaled + desc: CSS-scaled canvases get drawn correctly + canvas: 'width="50" height="25" style="width: 100px; height: 50px"' + manual: + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 50, 25); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 0, 25, 10); + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 1) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 1) + cr.rectangle(0, 0, 50, 20) + cr.fill() + +- name: 2d.canvas.reference + desc: CanvasRenderingContext2D.canvas refers back to its canvas + testing: + - 2d.canvas + code: | + @assert ctx.canvas === canvas; + +- name: 2d.canvas.readonly + desc: CanvasRenderingContext2D.canvas is readonly + testing: + - 2d.canvas.attribute + code: | + var c = document.createElement('canvas'); + var d = ctx.canvas; + @assert c !== d; + ctx.canvas = c; + @assert ctx.canvas === d; + +- meta: | + state = [ # some non-default values to test with + ('strokeStyle', '"#ff0000"'), + ('fillStyle', '"#ff0000"'), + ('globalAlpha', 0.5), + ('lineWidth', 0.5), + ('lineCap', '"round"'), + ('lineJoin', '"round"'), + ('miterLimit', 0.5), + ('shadowOffsetX', 5), + ('shadowOffsetY', 5), + ('shadowBlur', 5), + ('shadowColor', '"#ff0000"'), + ('globalCompositeOperation', '"copy"'), + ('font', '"25px serif"'), + ('textAlign', '"center"'), + ('textBaseline', '"bottom"'), + ] + for key,value in state: + tests.append( { + 'name': '2d.state.saverestore.%s' % key, + 'desc': 'save()/restore() works for %s' % key, + 'testing': [ '2d.state.%s' % key ], + 'code': + """// Test that restore() undoes any modifications + var old = ctx.%(key)s; + ctx.save(); + ctx.%(key)s = %(value)s; + ctx.restore(); + @assert ctx.%(key)s === old; + + // Also test that save() doesn't modify the values + ctx.%(key)s = %(value)s; + old = ctx.%(key)s; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against %(value)s + ctx.save(); + @assert ctx.%(key)s === old; + ctx.restore(); + """ % { 'key':key, 'value':value } + } ) + + tests.append( { + 'name': 'initial.reset.2dstate', + 'desc': 'Resetting the canvas state resets 2D state variables', + 'testing': [ 'initial.reset' ], + 'code': + """canvas.width = 100; + var default_val; + """ + "".join( + """ + default_val = ctx.%(key)s; + ctx.%(key)s = %(value)s; + canvas.width = 100; + @assert ctx.%(key)s === default_val; + """ % { 'key':key, 'value':value } + for key,value in state), + } ) + +- name: 2d.state.saverestore.transformation + desc: save()/restore() affects the current transformation matrix + testing: + - 2d.state.transformation + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.translate(200, 0); + ctx.restore(); + ctx.fillStyle = '#f00'; + ctx.fillRect(-200, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.state.saverestore.clip + desc: save()/restore() affects the clipping path + testing: + - 2d.state.clip + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 1, 1); + ctx.clip(); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.state.saverestore.path + desc: save()/restore() does not affect the current path + testing: + - 2d.state.path + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 100, 50); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.state.saverestore.bitmap + desc: save()/restore() does not affect the current bitmap + testing: + - 2d.state.bitmap + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.state.saverestore.stack + desc: save()/restore() can be nested as a stack + testing: + - 2d.state.save + - 2d.state.restore + code: | + ctx.lineWidth = 1; + ctx.save(); + ctx.lineWidth = 2; + ctx.save(); + ctx.lineWidth = 3; + @assert ctx.lineWidth === 3; + ctx.restore(); + @assert ctx.lineWidth === 2; + ctx.restore(); + @assert ctx.lineWidth === 1; + +- name: 2d.state.saverestore.stackdepth + desc: save()/restore() stack depth is not unreasonably limited + testing: + - 2d.state.save + - 2d.state.restore + code: | + var limit = 512; + for (var i = 1; i < limit; ++i) + { + ctx.save(); + ctx.lineWidth = i; + } + for (var i = limit-1; i > 0; --i) + { + @assert ctx.lineWidth === i; + ctx.restore(); + } + +- name: 2d.state.saverestore.underflow + desc: restore() with an empty stack has no effect + testing: + - 2d.state.restore.underflow + code: | + for (var i = 0; i < 16; ++i) + ctx.restore(); + ctx.lineWidth = 0.5; + ctx.restore(); + @assert ctx.lineWidth === 0.5; + + +- name: 2d.transformation.order + desc: Transformations are applied in the right order + testing: + - 2d.transformation.order + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(2, 1); + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -50, 50, 50); + @assert pixel 75,25 == 0,255,0,255; + expected: green + + +- name: 2d.transformation.scale.basic + desc: scale() works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(2, 4); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 12.5); + @assert pixel 90,40 == 0,255,0,255; + expected: green + +- name: 2d.transformation.scale.zero + desc: scale() with a scale factor of zero works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.translate(50, 0); + ctx.scale(0, 1); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + + ctx.save(); + ctx.translate(0, 25); + ctx.scale(1, 0); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + + canvas.toDataURL(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.scale.negative + desc: scale() with negative scale factors works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.scale(-1, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-50, 0, 50, 50); + ctx.restore(); + + ctx.save(); + ctx.scale(1, -1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, -50, 50, 50); + ctx.restore(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.scale.large + desc: scale() with large scale factors works + notes: Not really that large at all, but it hits the limits in Firefox. + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(1e5, 1e5); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 1, 1); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.scale.nonfinite + desc: scale() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + @nonfinite ctx.scale(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.scale.multiple + desc: Multiple scale()s combine + testing: + - 2d.transformation.scale.multiple + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 90,40 == 0,255,0,255; + expected: green + + +- name: 2d.transformation.rotate.zero + desc: rotate() by 0 does nothing + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.rotate.radians + desc: rotate() uses radians + testing: + - 2d.transformation.rotate.radians + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.rotate.direction + desc: rotate() is clockwise + testing: + - 2d.transformation.rotate.direction + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -100, 50, 100); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.rotate.wrap + desc: rotate() wraps large positive values correctly + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi) + // We need about pi +/- 0.001 in order to get correct-looking results + // 32-bit floats can store pi*4097 with precision 2^-10, so that should + // be safe enough on reasonable implementations + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,2 == 0,255,0,255; + @assert pixel 98,47 == 0,255,0,255; + expected: green + +- name: 2d.transformation.rotate.wrapnegative + desc: rotate() wraps large negative values correctly + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(-Math.PI * (1 + 4096)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,2 == 0,255,0,255; + @assert pixel 98,47 == 0,255,0,255; + expected: green + +- name: 2d.transformation.rotate.nonfinite + desc: rotate() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + @nonfinite ctx.rotate(<0.1 Infinity -Infinity NaN>); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.translate.basic + desc: translate() works + testing: + - 2d.transformation.translate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 90,40 == 0,255,0,255; + expected: green + +- name: 2d.transformation.translate.nonfinite + desc: translate() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + @nonfinite ctx.translate(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.transformation.transform.identity + desc: transform() with the identity matrix does nothing + testing: + - 2d.transformation.transform + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.transform(1,0, 0,1, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.transform.skewed + desc: transform() with skewy matrix transforms correctly + testing: + - 2d.transformation.transform + code: | + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.transform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + @assert pixel 21,11 == 0,255,0,255; + @assert pixel 79,11 == 0,255,0,255; + @assert pixel 21,39 == 0,255,0,255; + @assert pixel 79,39 == 0,255,0,255; + @assert pixel 39,19 == 0,255,0,255; + @assert pixel 61,19 == 0,255,0,255; + @assert pixel 39,31 == 0,255,0,255; + @assert pixel 61,31 == 0,255,0,255; + expected: green + +- name: 2d.transformation.transform.multiply + desc: transform() multiplies the CTM + testing: + - 2d.transformation.transform.multiply + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.transform(1,2, 3,4, 5,6); + ctx.transform(-2,1, 3/2,-1/2, 1,-2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.transformation.transform.nonfinite + desc: transform() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + @nonfinite ctx.transform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.transformation.setTransform.skewed + testing: + - 2d.transformation.setTransform + code: | + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.setTransform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + @assert pixel 21,11 == 0,255,0,255; + @assert pixel 79,11 == 0,255,0,255; + @assert pixel 21,39 == 0,255,0,255; + @assert pixel 79,39 == 0,255,0,255; + @assert pixel 39,19 == 0,255,0,255; + @assert pixel 61,19 == 0,255,0,255; + @assert pixel 39,31 == 0,255,0,255; + @assert pixel 61,31 == 0,255,0,255; + expected: green + +- name: 2d.transformation.setTransform.multiple + testing: + - 2d.transformation.setTransform.identity + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.setTransform(1/2,0, 0,1/2, 0,0); + ctx.setTransform(2,0, 0,2, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 75,35 == 0,255,0,255; + expected: green + +- name: 2d.transformation.setTransform.nonfinite + desc: setTransform() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + @nonfinite ctx.setTransform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.composite.globalAlpha.range + testing: + - 2d.composite.globalAlpha.range + code: | + ctx.globalAlpha = 0.5; + var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = 1.1; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = -0.1; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = 0; + @assert ctx.globalAlpha === 0; + ctx.globalAlpha = 1; + @assert ctx.globalAlpha === 1; + +- name: 2d.composite.globalAlpha.invalid + testing: + - 2d.composite.globalAlpha.range + code: | + ctx.globalAlpha = 0.5; + var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = Infinity; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = -Infinity; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = NaN; + @assert ctx.globalAlpha === a; + +- name: 2d.composite.globalAlpha.default + testing: + - 2d.composite.globalAlpha.default + code: | + @assert ctx.globalAlpha === 1.0; + +- name: 2d.composite.globalAlpha.fill + testing: + - 2d.composite.globalAlpha.shape + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + expected: green + +- name: 2d.composite.globalAlpha.image + testing: + - 2d.composite.globalAlpha.image + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.drawImage(document.getElementById('red.png'), 0, 0); + @assert pixel 50,25 ==~ 2,253,0,255; + expected: green + +- name: 2d.composite.globalAlpha.canvas + testing: + - 2d.composite.globalAlpha.image + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.drawImage(canvas2, 0, 0); + @assert pixel 50,25 ==~ 2,253,0,255; + expected: green + +- name: 2d.composite.globalAlpha.imagepattern + testing: + - 2d.composite.globalAlpha.image + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = ctx.createPattern(document.getElementById('red.png'), 'no-repeat'); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + expected: green + +- name: 2d.composite.globalAlpha.canvaspattern + testing: + - 2d.composite.globalAlpha.image + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = ctx.createPattern(canvas2, 'no-repeat'); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + expected: green + +- name: 2d.composite.globalAlpha.canvascopy + testing: + - 2d.composite.globalAlpha.image + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.globalCompositeOperation = 'copy' + ctx.globalAlpha = 0.51; + ctx.drawImage(canvas2, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,130; + expected: green + + +- meta: | + # Composite operation tests + # <http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2007-March/010608.html> + ops = [ + # name FA FB + ('source-over', '1', '1-aA'), + ('destination-over', '1-aB', '1'), + ('source-in', 'aB', '0'), + ('destination-in', '0', 'aA'), + ('source-out', '1-aB', '0'), + ('destination-out', '0', '1-aA'), + ('source-atop', 'aB', '1-aA'), + ('destination-atop', '1-aB', 'aA'), + ('xor', '1-aB', '1-aA'), + ('copy', '1', '0'), + ('lighter', '1', '1'), + ] + + # The ones that change the output when src = (0,0,0,0): + ops_trans = [ 'source-in', 'destination-in', 'source-out', 'destination-atop', 'copy' ]; + + def calc_output((RA, GA, BA, aA), (RB, GB, BB, aB), FA_code, FB_code): + rA, gA, bA = RA*aA, GA*aA, BA*aA + rB, gB, bB = RB*aB, GB*aB, BB*aB + + FA = eval(FA_code) + FB = eval(FB_code) + + rO = rA*FA + rB*FB + gO = gA*FA + gB*FB + bO = bA*FA + bB*FB + aO = aA*FA + aB*FB + + rO = min(255, rO) + gO = min(255, gO) + bO = min(255, bO) + aO = min(1, aO) + + if aO: + RO = rO / aO + GO = gO / aO + BO = bO / aO + else: RO = GO = BO = 0 + + return (RO, GO, BO, aO) + + def to_test((r,g,b,a)): + return '%d,%d,%d,%d' % (round(r), round(g), round(b), round(a*255)) + def to_cairo((r,g,b,a)): + return '%f,%f,%f,%f' % (r/255., g/255., b/255., a) + + for (name, src, dest) in [ + ('solid', (255, 255, 0, 1.0), (0, 255, 255, 1.0)), + ('transparent', (0, 0, 255, 0.75), (0, 255, 0, 0.5)), + # catches the atop, xor and lighter bugs in Opera 9.10 + ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, src, to_test(expected)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % to_cairo(expected), + } ) + + for (name, src, dest) in [ ('image', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow75.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.drawImage(document.getElementById('yellow75.png'), 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % to_cairo(expected), + } ) + + for (name, src, dest) in [ ('canvas', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow75.png' ], + 'code': """ + var canvas2 = document.createElement('canvas'); + canvas2.width = canvas.width; + canvas2.height = canvas.height; + var ctx2 = canvas2.getContext('2d'); + ctx2.drawImage(document.getElementById('yellow75.png'), 0, 0); + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.drawImage(canvas2, 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % to_cairo(expected), + } ) + + + for (name, src, dest) in [ ('uncovered.fill', (0, 0, 255, 0.75), (0, 255, 0, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.fillStyle = 'rgba%s'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, src, to_test(expected0)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % (to_cairo(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.image', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.drawImage(document.getElementById('yellow.png'), 40, 40, 10, 10, 40, 50, 10, 10); + @assert pixel 15,15 ==~ %s +/- 5; + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected0), to_test(expected0)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % (to_cairo(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.nocontext', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + var canvas2 = document.createElement('canvas'); + ctx.drawImage(canvas2, 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected0)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % (to_cairo(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.pattern', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.fillStyle = ctx.createPattern(document.getElementById('yellow.png'), 'no-repeat'); + ctx.fillRect(0, 50, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected0)), + 'expected': """size 100 50 + cr.set_source_rgba(%s) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % (to_cairo(expected0)), + } ) + + for op, FA_code, FB_code in ops: + tests.append( { + 'name': '2d.composite.clip.%s' % (op), + 'desc': 'fill() does not affect pixels outside the clip region.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.rect(-20, -20, 10, 10); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + """ % (op), + 'expected': 'green' + } ) + +- name: 2d.composite.operation.get + testing: + - 2d.composite.operation + code: | + var modes = ['source-atop', 'source-in', 'source-out', 'source-over', + 'destination-atop', 'destination-in', 'destination-out', 'destination-over', + 'lighter', 'copy', 'xor']; + for (var i = 0; i < modes.length; ++i) + { + ctx.globalCompositeOperation = modes[i]; + @assert ctx.globalCompositeOperation === modes[i]; + } + +- name: 2d.composite.operation.unrecognised + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'nonexistent'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.darker + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'darker'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.over + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'over'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.clear + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'clear'; + @assert ctx.globalCompositeOperation === 'clear'; + +- name: 2d.composite.operation.highlight + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'highlight'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.nullsuffix + testing: + - 2d.composite.operation.exact + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'source-over\0'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.casesensitive + testing: + - 2d.composite.operation.casesensitive + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'Source-over'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.default + testing: + - 2d.composite.operation.default + code: | + @assert ctx.globalCompositeOperation === 'source-over'; + + +- meta: | + # Colour parsing tests + + # Try most of the CSS3 Color <color> values - http://www.w3.org/TR/css3-color/#colorunits + big_float = '1' + ('0' * 39) + big_double = '1' + ('0' * 310) + for name, string, r,g,b,a, notes in [ + ('html4', 'limE', 0,255,0,255, ""), + ('hex3', '#0f0', 0,255,0,255, ""), + ('hex4', '#0f0f', 0,255,0,255, ""), + ('hex6', '#00fF00', 0,255,0,255, ""), + ('hex8', '#00ff00ff', 0,255,0,255, ""), + ('rgb-num', 'rgb(0,255,0)', 0,255,0,255, ""), + ('rgb-clamp-1', 'rgb(-1000, 1000, -1000)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-2', 'rgb(-200%, 200%, -200%)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-3', 'rgb(-2147483649, 4294967298, -18446744073709551619)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-4', 'rgb(-'+big_float+', '+big_float+', -'+big_float+')', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-5', 'rgb(-'+big_double+', '+big_double+', -'+big_double+')', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-percent', 'rgb(0% ,100% ,0%)', 0,255,0,255, 'CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)'), + ('rgb-eof', 'rgb(0, 255, 0', 0,255,0,255, ""), # see CSS2.1 4.2 "Unexpected end of style sheet" + ('rgba-solid-1', 'rgba( 0 , 255 , 0 , 1 )', 0,255,0,255, ""), + ('rgba-solid-2', 'rgba( 0 , 255 , 0 , 1.0 )', 0,255,0,255, ""), + ('rgba-solid-3', 'rgba( 0 , 255 , 0 , +1 )', 0,255,0,255, ""), + ('rgba-solid-4', 'rgba( -0 , 255 , +0 , 1 )', 0,255,0,255, ""), + ('rgba-num-1', 'rgba( 0 , 255 , 0 , .499 )', 0,255,0,127, ""), + ('rgba-num-2', 'rgba( 0 , 255 , 0 , 0.499 )', 0,255,0,127, ""), + ('rgba-percent', 'rgba(0%,100%,0%,0.499)', 0,255,0,127, ""), # 0.499*255 rounds to 127, both down and nearest, so it should be safe + ('rgba-clamp-1', 'rgba(0, 255, 0, -2)', 0,0,0,0, ""), + ('rgba-clamp-2', 'rgba(0, 255, 0, 2)', 0,255,0,255, ""), + ('rgba-eof', 'rgba(0, 255, 0, 1', 0,255,0,255, ""), + ('transparent-1', 'transparent', 0,0,0,0, ""), + ('transparent-2', 'TrAnSpArEnT', 0,0,0,0, ""), + ('hsl-1', 'hsl(120, 100%, 50%)', 0,255,0,255, ""), + ('hsl-2', 'hsl( -240 , 100% , 50% )', 0,255,0,255, ""), + ('hsl-3', 'hsl(360120, 100%, 50%)', 0,255,0,255, ""), + ('hsl-4', 'hsl(-360240, 100%, 50%)', 0,255,0,255, ""), + ('hsl-5', 'hsl(120.0, 100.0%, 50.0%)', 0,255,0,255, ""), + ('hsl-6', 'hsl(+120, +100%, +50%)', 0,255,0,255, ""), + ('hsl-clamp-1', 'hsl(120, 200%, 50%)', 0,255,0,255, ""), + ('hsl-clamp-2', 'hsl(120, -200%, 49.9%)', 127,127,127,255, ""), + ('hsl-clamp-3', 'hsl(120, 100%, 200%)', 255,255,255,255, ""), + ('hsl-clamp-4', 'hsl(120, 100%, -200%)', 0,0,0,255, ""), + ('hsla-1', 'hsla(120, 100%, 50%, 0.499)', 0,255,0,127, ""), + ('hsla-2', 'hsla( 120.0 , 100.0% , 50.0% , 1 )', 0,255,0,255, ""), + ('hsla-clamp-1', 'hsla(120, 200%, 50%, 1)', 0,255,0,255, ""), + ('hsla-clamp-2', 'hsla(120, -200%, 49.9%, 1)', 127,127,127,255, ""), + ('hsla-clamp-3', 'hsla(120, 100%, 200%, 1)', 255,255,255,255, ""), + ('hsla-clamp-4', 'hsla(120, 100%, -200%, 1)', 0,0,0,255, ""), + ('hsla-clamp-5', 'hsla(120, 100%, 50%, 2)', 0,255,0,255, ""), + ('hsla-clamp-6', 'hsla(120, 100%, 0%, -2)', 0,0,0,0, ""), + ('svg-1', 'gray', 128,128,128,255, ""), + ('svg-2', 'grey', 128,128,128,255, ""), + # css-color-4 rgb() color function + # https://drafts.csswg.org/css-color/#numeric-rgb + ('css-color-4-rgb-1', 'rgb(0, 255.0, 0)', 0,255,0,255, ""), + ('css-color-4-rgb-2', 'rgb(0, 255, 0, 0.2)', 0,255,0,51, ""), + ('css-color-4-rgb-3', 'rgb(0, 255, 0, 20%)', 0,255,0,51, ""), + ('css-color-4-rgb-4', 'rgb(0 255 0)', 0,255,0,255, ""), + ('css-color-4-rgb-5', 'rgb(0 255 0 / 0.2)', 0,255,0,51, ""), + ('css-color-4-rgb-6', 'rgb(0 255 0 / 20%)', 0,255,0,51, ""), + ('css-color-4-rgba-1', 'rgba(0, 255.0, 0)', 0,255,0,255, ""), + ('css-color-4-rgba-2', 'rgba(0, 255, 0, 0.2)', 0,255,0,51, ""), + ('css-color-4-rgba-3', 'rgba(0, 255, 0, 20%)', 0,255,0,51, ""), + ('css-color-4-rgba-4', 'rgba(0 255 0)', 0,255,0,255, ""), + ('css-color-4-rgba-5', 'rgba(0 255 0 / 0.2)', 0,255,0,51, ""), + ('css-color-4-rgba-6', 'rgba(0 255 0 / 20%)', 0,255,0,51, ""), + # css-color-4 hsl() color function + # https://drafts.csswg.org/css-color/#the-hsl-notation + ('css-color-4-hsl-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""), + ('css-color-4-hsl-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""), + ('css-color-4-hsla-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""), + # currentColor is handled later + ]: + # TODO: test by retrieving fillStyle, instead of actually drawing? + # TODO: test strokeStyle, shadowColor in the same way + test = { + 'name': '2d.fillStyle.parse.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'notes': notes, + 'code': """ + ctx.fillStyle = '#f00'; + ctx.fillStyle = '%s'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == %d,%d,%d,%d; + """ % (string, r,g,b,a), + 'expected': """size 100 50 + cr.set_source_rgba(%f, %f, %f, %f) + cr.rectangle(0, 0, 100, 50) + cr.fill() + """ % (r/255., g/255., b/255., a/255.), + } + tests.append(test) + + # Also test that invalid colours are ignored + for name, string in [ + ('hex1', '#f'), + ('hex2', '#f0'), + ('hex3', '#g00'), + ('hex4', '#fg00'), + ('hex5', '#ff000'), + ('hex6', '#fg0000'), + ('hex7', '#ff0000f'), + ('hex8', '#fg0000ff'), + ('rgb-1', 'rgb(255.0, 0, 0,)'), + ('rgb-2', 'rgb(100%, 0, 0)'), + ('rgb-3', 'rgb(255, - 1, 0)'), + ('rgba-1', 'rgba(100%, 0, 0, 1)'), + ('rgba-2', 'rgba(255, 0, 0, 1. 0)'), + ('rgba-3', 'rgba(255, 0, 0, 1.)'), + ('rgba-4', 'rgba(255, 0, 0, '), + ('rgba-5', 'rgba(255, 0, 0, 1,)'), + ('hsl-1', 'hsl(0%, 100%, 50%)'), + ('hsl-2', 'hsl(z, 100%, 50%)'), + ('hsl-3', 'hsl(0, 0, 50%)'), + ('hsl-4', 'hsl(0, 100%, 0)'), + ('hsl-5', 'hsl(0, 100.%, 50%)'), + ('hsl-6', 'hsl(0, 100%, 50%,)'), + ('hsla-1', 'hsla(0%, 100%, 50%, 1)'), + ('hsla-2', 'hsla(0, 0, 50%, 1)'), + ('hsla-3', 'hsla(0, 0, 50%, 1,)'), + ('name-1', 'darkbrown'), + ('name-2', 'firebrick1'), + ('name-3', 'red blue'), + ('name-4', '"red"'), + ('name-5', '"red'), + # css-color-4 color function + # comma and comma-less expressions should not mix together. + ('css-color-4-rgb-1', 'rgb(255, 0, 0 / 1)'), + ('css-color-4-rgb-2', 'rgb(255 0 0, 1)'), + ('css-color-4-rgb-3', 'rgb(255, 0 0)'), + ('css-color-4-rgba-1', 'rgba(255, 0, 0 / 1)'), + ('css-color-4-rgba-2', 'rgba(255 0 0, 1)'), + ('css-color-4-rgba-3', 'rgba(255, 0 0)'), + ('css-color-4-hsl-1', 'hsl(0, 100%, 50% / 1)'), + ('css-color-4-hsl-2', 'hsl(0 100% 50%, 1)'), + ('css-color-4-hsl-3', 'hsl(0, 100% 50%)'), + ('css-color-4-hsla-1', 'hsla(0, 100%, 50% / 1)'), + ('css-color-4-hsla-2', 'hsla(0 100% 50%, 1)'), + ('css-color-4-hsla-3', 'hsla(0, 100% 50%)'), + # trailing slash + ('css-color-4-rgb-4', 'rgb(0 0 0 /)'), + ('css-color-4-rgb-5', 'rgb(0, 0, 0 /)'), + ('css-color-4-hsl-4', 'hsl(0 100% 50% /)'), + ('css-color-4-hsl-5', 'hsl(0, 100%, 50% /)'), + ]: + test = { + 'name': '2d.fillStyle.parse.invalid.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'code': """ + ctx.fillStyle = '#0f0'; + try { ctx.fillStyle = '%s'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + """ % string, + 'expected': 'green' + } + tests.append(test) + + # Some can't have positive tests, only negative tests, because we don't know what colour they're meant to be + for name, string in [ + ('system', 'ThreeDDarkShadow'), + #('flavor', 'flavor'), # removed from latest CSS3 Color drafts + ]: + test = { + 'name': '2d.fillStyle.parse.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'code': """ + ctx.fillStyle = '#f00'; + ctx.fillStyle = '%s'; + @assert ctx.fillStyle =~ /^#(?!(FF0000|ff0000|f00)$)/; // test that it's not red + """ % (string,), + } + tests.append(test) + +- name: 2d.fillStyle.parse.current.basic + desc: currentColor is computed from the canvas element + testing: + - 2d.colours.parse + - 2d.currentColor.onset + code: | + canvas.setAttribute('style', 'color: #0f0'); + ctx.fillStyle = '#f00'; + ctx.fillStyle = 'currentColor'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillStyle.parse.current.changed + desc: currentColor is computed when the attribute is set, not when it is painted + testing: + - 2d.colours.parse + - 2d.currentColor.onset + code: | + canvas.setAttribute('style', 'color: #0f0'); + ctx.fillStyle = '#f00'; + ctx.fillStyle = 'currentColor'; + canvas.setAttribute('style', 'color: #f00'); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillStyle.parse.current.removed + desc: currentColor is solid black when the canvas element is not in a document + testing: + - 2d.colours.parse + - 2d.currentColor.outofdoc + code: | + // Try not to let it undetectably incorrectly pick up opaque-black + // from other parts of the document: + document.body.parentNode.setAttribute('style', 'color: #f00'); + document.body.setAttribute('style', 'color: #f00'); + canvas.setAttribute('style', 'color: #f00'); + + var canvas2 = document.createElement('canvas'); + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillStyle = 'currentColor'; + ctx2.fillRect(0, 0, 100, 50); + ctx.drawImage(canvas2, 0, 0); + + document.body.parentNode.removeAttribute('style'); + document.body.removeAttribute('style'); + + @assert pixel 50,25 == 0,0,0,255; + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.fillStyle.invalidstring + testing: + - 2d.colours.invalidstring + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillStyle = 'invalid'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillStyle.invalidtype + testing: + - 2d.colours.invalidtype + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillStyle = null; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillStyle.get.solid + testing: + - 2d.colours.getcolour + - 2d.serializecolour.solid + code: | + ctx.fillStyle = '#fa0'; + @assert ctx.fillStyle === '#ffaa00'; + +- name: 2d.fillStyle.get.semitransparent + testing: + - 2d.colours.getcolour + - 2d.serializecolour.transparent + code: | + ctx.fillStyle = 'rgba(255,255,255,0.45)'; + @assert ctx.fillStyle =~ /^rgba\(255, 255, 255, 0\.4\d+\)$/; + +- name: 2d.fillStyle.get.transparent + testing: + - 2d.colours.getcolour + - 2d.serializecolour.transparent + code: | + ctx.fillStyle = 'rgba(0,0,0,0)'; + @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)'; + +- name: 2d.fillStyle.default + testing: + - 2d.colours.default + code: | + @assert ctx.fillStyle === '#000000'; + +- name: 2d.strokeStyle.default + testing: + - 2d.colours.default + code: | + @assert ctx.strokeStyle === '#000000'; + + +- name: 2d.gradient.object.type + desc: window.CanvasGradient exists and has the right properties + testing: + - 2d.canvasGradient.type + notes: *bindings + code: | + @assert window.CanvasGradient !== undefined; + @assert window.CanvasGradient.prototype.addColorStop !== undefined; + +- name: 2d.gradient.object.return + desc: createLinearGradient() and createRadialGradient() returns objects implementing CanvasGradient + testing: + - 2d.gradient.linear.return + - 2d.gradient.radial.return + code: | + window.CanvasGradient.prototype.thisImplementsCanvasGradient = true; + + var g1 = ctx.createLinearGradient(0, 0, 100, 0); + @assert g1.addColorStop !== undefined; + @assert g1.thisImplementsCanvasGradient === true; + + var g2 = ctx.createRadialGradient(0, 0, 10, 0, 0, 20); + @assert g2.addColorStop !== undefined; + @assert g2.thisImplementsCanvasGradient === true; + +- name: 2d.gradient.interpolate.solid + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.interpolate.colour + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 191,191,63,255 +/- 3; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 3; + @assert pixel 75,25 ==~ 63,63,191,255 +/- 3; + expected: | + size 100 50 + g = cairo.LinearGradient(0, 0, 100, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.gradient.interpolate.alpha + testing: + - 2d.gradient.interpolate.linear + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(0,0,255, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 191,191,63,255 +/- 3; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 3; + @assert pixel 75,25 ==~ 63,63,191,255 +/- 3; + expected: | + size 100 50 + g = cairo.LinearGradient(0, 0, 100, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.gradient.interpolate.colouralpha + testing: + - 2d.gradient.interpolate.alpha + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(255,255,0, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 190,190,65,65 +/- 3; + @assert pixel 50,25 ==~ 126,126,128,128 +/- 3; + @assert pixel 75,25 ==~ 62,62,192,192 +/- 3; + expected: | + size 100 50 + g = cairo.LinearGradient(0, 0, 100, 0) + g.add_color_stop_rgba(0, 1,1,0, 0) + g.add_color_stop_rgba(1, 0,0,1, 1) + cr.set_source(g) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.gradient.interpolate.outside + testing: + - 2d.gradient.outside.first + - 2d.gradient.outside.last + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(25, 0, 75, 0); + g.addColorStop(0.4, '#0f0'); + g.addColorStop(0.6, '#0f0'); + + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 80,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.gradient.interpolate.zerosize.fill + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.rect(0, 0, 100, 50); + ctx.fill(); + @assert pixel 40,20 == 0,255,0,255; + expected: green + +- name: 2d.gradient.interpolate.zerosize.stroke + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.strokeStyle = g; + ctx.rect(20, 20, 60, 10); + ctx.stroke(); + @assert pixel 19,19 == 0,255,0,255; + @assert pixel 20,19 == 0,255,0,255; + @assert pixel 21,19 == 0,255,0,255; + @assert pixel 19,20 == 0,255,0,255; + @assert pixel 20,20 == 0,255,0,255; + @assert pixel 21,20 == 0,255,0,255; + @assert pixel 19,21 == 0,255,0,255; + @assert pixel 20,21 == 0,255,0,255; + @assert pixel 21,21 == 0,255,0,255; + expected: green + +- name: 2d.gradient.interpolate.zerosize.fillRect + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 40,20 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.interpolate.zerosize.strokeRect + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.strokeStyle = g; + ctx.strokeRect(20, 20, 60, 10); + @assert pixel 19,19 == 0,255,0,255; + @assert pixel 20,19 == 0,255,0,255; + @assert pixel 21,19 == 0,255,0,255; + @assert pixel 19,20 == 0,255,0,255; + @assert pixel 20,20 == 0,255,0,255; + @assert pixel 21,20 == 0,255,0,255; + @assert pixel 19,21 == 0,255,0,255; + @assert pixel 20,21 == 0,255,0,255; + @assert pixel 21,21 == 0,255,0,255; + expected: green + +- name: 2d.gradient.interpolate.zerosize.fillText + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.font = '100px sans-serif'; + ctx.fillText("AA", 0, 50); + _assertGreen(ctx, 100, 50); + expected: green + +- name: 2d.gradient.interpolate.zerosize.strokeText + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.strokeStyle = g; + ctx.font = '100px sans-serif'; + ctx.strokeText("AA", 0, 50); + _assertGreen(ctx, 100, 50); + expected: green + + +- name: 2d.gradient.interpolate.vertical + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 0, 50); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,12 ==~ 191,191,63,255 +/- 10; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 5; + @assert pixel 50,37 ==~ 63,63,191,255 +/- 10; + expected: | + size 100 50 + g = cairo.LinearGradient(0, 0, 0, 50) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.gradient.interpolate.multiple + testing: + - 2d.gradient.interpolate.linear + code: | + canvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.5, '#0ff'); + g.addColorStop(1, '#f0f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + @assert pixel 50,25 ==~ 127,255,127,255 +/- 3; + @assert pixel 100,25 ==~ 0,255,255,255 +/- 3; + @assert pixel 150,25 ==~ 127,127,255,255 +/- 3; + expected: | + size 200 50 + g = cairo.LinearGradient(0, 0, 200, 0) + g.add_color_stop_rgb(0.0, 1,1,0) + g.add_color_stop_rgb(0.5, 0,1,1) + g.add_color_stop_rgb(1.0, 1,0,1) + cr.set_source(g) + cr.rectangle(0, 0, 200, 50) + cr.fill() + +- name: 2d.gradient.interpolate.overlap + testing: + - 2d.gradient.interpolate.overlap + code: | + canvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.25, '#00f'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#ff0'); + g.addColorStop(0.5, '#00f'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.75, '#00f'); + g.addColorStop(0.75, '#f00'); + g.addColorStop(0.75, '#ff0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + @assert pixel 49,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 51,25 ==~ 255,255,0,255 +/- 16; + @assert pixel 99,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 101,25 ==~ 255,255,0,255 +/- 16; + @assert pixel 149,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 151,25 ==~ 255,255,0,255 +/- 16; + expected: | + size 200 50 + g = cairo.LinearGradient(0, 0, 50, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(0, 0, 50, 50) + cr.fill() + + g = cairo.LinearGradient(50, 0, 100, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(50, 0, 50, 50) + cr.fill() + + g = cairo.LinearGradient(100, 0, 150, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(100, 0, 50, 50) + cr.fill() + + g = cairo.LinearGradient(150, 0, 200, 0) + g.add_color_stop_rgb(0, 1,1,0) + g.add_color_stop_rgb(1, 0,0,1) + cr.set_source(g) + cr.rectangle(150, 0, 50, 50) + cr.fill() + +- name: 2d.gradient.interpolate.overlap2 + testing: + - 2d.gradient.interpolate.overlap + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ]; + for (var p = 0; p < ps.length; ++p) + { + g.addColorStop(ps[p], '#0f0'); + for (var i = 0; i < 15; ++i) + g.addColorStop(ps[p], '#f00'); + g.addColorStop(ps[p], '#0f0'); + } + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 30,25 == 0,255,0,255; + @assert pixel 40,25 == 0,255,0,255; + @assert pixel 60,25 == 0,255,0,255; + @assert pixel 80,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.empty + testing: + - 2d.gradient.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 0, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.gradient.object.update + testing: + - 2d.gradient.update + code: | + var g = ctx.createLinearGradient(-100, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + g.addColorStop(0.1, '#0f0'); + g.addColorStop(0.9, '#0f0'); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.gradient.object.compare + testing: + - 2d.gradient.object + code: | + var g1 = ctx.createLinearGradient(0, 0, 100, 0); + var g2 = ctx.createLinearGradient(0, 0, 100, 0); + @assert g1 !== g2; + ctx.fillStyle = g1; + @assert ctx.fillStyle === g1; + +- name: 2d.gradient.object.crosscanvas + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = document.createElement('canvas').getContext('2d').createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.gradient.object.current + testing: + - 2d.currentColor.gradient + code: | + canvas.setAttribute('style', 'color: #f00'); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'currentColor'); + g.addColorStop(1, 'currentColor'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,0,0,255; + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.gradient.object.invalidoffset + testing: + - 2d.gradient.invalidoffset + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + @assert throws INDEX_SIZE_ERR g.addColorStop(-1, '#000'); + @assert throws INDEX_SIZE_ERR g.addColorStop(2, '#000'); + @assert throws TypeError g.addColorStop(Infinity, '#000'); + @assert throws TypeError g.addColorStop(-Infinity, '#000'); + @assert throws TypeError g.addColorStop(NaN, '#000'); + +- name: 2d.gradient.object.invalidcolour + testing: + - 2d.gradient.invalidcolour + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + @assert throws SYNTAX_ERR g.addColorStop(0, ""); + @assert throws SYNTAX_ERR g.addColorStop(0, 'null'); + @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined'); + @assert throws SYNTAX_ERR g.addColorStop(0, null); + @assert throws SYNTAX_ERR g.addColorStop(0, undefined); + + +- name: 2d.gradient.linear.nonfinite + desc: createLinearGradient() throws TypeError if arguments are not finite + notes: *bindings + testing: + - 2d.gradient.linear.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createLinearGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + +- name: 2d.gradient.linear.transform.1 + desc: Linear gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.linear.transform + code: | + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.linear.transform.2 + desc: Linear gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.linear.transform + code: | + ctx.translate(100, 0); + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-150, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.linear.transform.3 + desc: Linear gradient transforms do not experience broken caching effects + testing: + - 2d.gradient.linear.transform + code: | + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.negative + desc: createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative + testing: + - 2d.gradient.radial.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); + +- name: 2d.gradient.radial.nonfinite + desc: createRadialGradient() throws TypeError if arguments are not finite + notes: *bindings + testing: + - 2d.gradient.radial.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createRadialGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>); + +- name: 2d.gradient.radial.inside1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.inside2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.inside3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(0.993, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.outside1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.outside2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.outside3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.001, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.touch1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.radial.touch2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150); + g.addColorStop(0, '#f00'); + g.addColorStop(0.01, '#0f0'); + g.addColorStop(0.99, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.touch3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.radial.equal + testing: + - 2d.gradient.radial.equal + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.radial.cone.behind + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.radial.cone.front + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.cone.bottom + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.cone.top + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.cone.beside + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.gradient.radial.cone.cylinder + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.cone.shape1 + testing: + - 2d.gradient.radial.rendering + code: | + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(30+tol, 40); + ctx.lineTo(110, -20+tol); + ctx.lineTo(110, 100-tol); + ctx.fill(); + + var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.cone.shape2 + testing: + - 2d.gradient.radial.rendering + code: | + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(30-tol, 40); + ctx.lineTo(110, -20-tol); + ctx.lineTo(110, 100+tol); + ctx.fill(); + + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.transform.1 + desc: Radial gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.radial.transform + code: | + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.transform.2 + desc: Radial gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.radial.transform + code: | + ctx.translate(100, 0); + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.gradient.radial.transform.3 + desc: Radial gradient transforms do not experience broken caching effects + testing: + - 2d.gradient.radial.transform + code: | + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + + + + + + +- name: 2d.pattern.basic.type + testing: + - 2d.pattern.return + images: + - green.png + code: | + @assert window.CanvasPattern !== undefined; + + window.CanvasPattern.prototype.thisImplementsCanvasPattern = true; + + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + @assert pattern.thisImplementsCanvasPattern; + +- name: 2d.pattern.basic.image + testing: + - 2d.pattern.painting + images: + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.basic.canvas + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + var pattern = ctx.createPattern(canvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.basic.zerocanvas + testing: + - 2d.pattern.zerocanvas + code: | + canvas.width = 0; + canvas.height = 10; + @assert canvas.width === 0; + @assert canvas.height === 10; + @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat'); + + canvas.width = 10; + canvas.height = 0; + @assert canvas.width === 10; + @assert canvas.height === 0; + @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat'); + + canvas.width = 0; + canvas.height = 0; + @assert canvas.width === 0; + @assert canvas.height === 0; + @assert throws INVALID_STATE_ERR ctx.createPattern(canvas, 'repeat'); + +- name: 2d.pattern.basic.nocontext + testing: + - 2d.pattern.painting + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var pattern = ctx.createPattern(canvas2, 'no-repeat'); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.image.undefined + testing: + - 2d.pattern.IDL + notes: *bindings + code: | + @assert throws TypeError ctx.createPattern(undefined, 'repeat'); + +- name: 2d.pattern.image.null + testing: + - 2d.pattern.IDL + notes: *bindings + code: | + @assert throws TypeError ctx.createPattern(null, 'repeat'); + +- name: 2d.pattern.image.string + testing: + - 2d.pattern.IDL + notes: *bindings + code: | + @assert throws TypeError ctx.createPattern('../images/red.png', 'repeat'); + +- name: 2d.pattern.image.incomplete.nosrc + testing: + - 2d.pattern.incomplete.image + mozilla: { throws } + code: | + var img = new Image(); + @assert ctx.createPattern(img, 'repeat') === null; + +- name: 2d.pattern.image.incomplete.immediate + testing: + - 2d.pattern.incomplete.image + images: + - red.png + code: | + var img = new Image(); + img.src = '../images/red.png'; + // This triggers the "update the image data" algorithm. + // The image will not go to the "completely available" state + // until a fetch task in the networking task source is processed, + // so the image must not be fully decodable yet: + @assert ctx.createPattern(img, 'repeat') === null; @moz-todo + +- name: 2d.pattern.image.incomplete.reload + testing: + - 2d.pattern.incomplete.image + images: + - yellow.png + - red.png + code: | + var img = document.getElementById('yellow.png'); + img.src = '../images/red.png'; + // This triggers the "update the image data" algorithm, + // and resets the image to the "unavailable" state. + // The image will not go to the "completely available" state + // until a fetch task in the networking task source is processed, + // so the image must not be fully decodable yet: + @assert ctx.createPattern(img, 'repeat') === null; @moz-todo + +- name: 2d.pattern.image.incomplete.emptysrc + testing: + - 2d.pattern.incomplete.image + images: + - red.png + mozilla: { throws } + code: | + var img = document.getElementById('red.png'); + img.src = ""; + @assert ctx.createPattern(img, 'repeat') === null; + +- name: 2d.pattern.image.incomplete.removedsrc + testing: + - 2d.pattern.incomplete.image + images: + - red.png + mozilla: { throws } + code: | + var img = document.getElementById('red.png'); + img.removeAttribute('src'); + @assert ctx.createPattern(img, 'repeat') === null; + +- name: 2d.pattern.image.broken + testing: + - 2d.pattern.incomplete.image + images: + - broken.png + code: | + var img = document.getElementById('broken.png'); + @assert throws INVALID_STATE_ERR ctx.createPattern(img, 'repeat'); + +- name: 2d.pattern.repeat.empty + testing: + - 2d.pattern.missing + images: + - green-1x1.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('green-1x1.png'); + var pattern = ctx.createPattern(img, ""); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 200, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.repeat.null + testing: + - 2d.pattern.unrecognised + code: | + @assert ctx.createPattern(canvas, null) != null; + +- name: 2d.pattern.repeat.undefined + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(canvas, undefined); + +- name: 2d.pattern.repeat.unrecognised + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(canvas, "invalid"); + +- name: 2d.pattern.repeat.unrecognisednull + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(canvas, "null"); + +- name: 2d.pattern.repeat.case + testing: + - 2d.pattern.exact + code: | + @assert throws SYNTAX_ERR ctx.createPattern(canvas, "Repeat"); + +- name: 2d.pattern.repeat.nullsuffix + testing: + - 2d.pattern.exact + code: | + @assert throws SYNTAX_ERR ctx.createPattern(canvas, "repeat\0"); + +- name: 2d.pattern.modify.image1 + testing: + - 2d.pattern.modify + images: + - green.png + code: | + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + img.src = '/images/red.png'; + expected: green + +- name: 2d.pattern.modify.image2 + testing: + - 2d.pattern.modify + images: + - green.png + code: | + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + deferTest(); + img.onload = t.step_func_done(function () + { + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + img.src = '/images/red.png'; + expected: green + +- name: 2d.pattern.modify.canvas1 + testing: + - 2d.pattern.modify + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + var pattern = ctx.createPattern(canvas2, 'no-repeat'); + + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.modify.canvas2 + testing: + - 2d.pattern.modify + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + var pattern = ctx.createPattern(canvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.crosscanvas + images: + - green.png + code: | + var img = document.getElementById('green.png'); + + var pattern = document.createElement('canvas').getContext('2d').createPattern(img, 'no-repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.norepeat.basic + testing: + - 2d.pattern.painting + images: + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.norepeat.outside + testing: + - 2d.pattern.painting + images: + - red.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + ctx.fillRect(-100, 0, 100, 50); + ctx.fillRect(0, 50, 100, 50); + ctx.fillRect(100, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.norepeat.coord1 + testing: + - 2d.pattern.painting + images: + - green.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 0); + ctx.fillRect(-50, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.norepeat.coord2 + testing: + - 2d.pattern.painting + images: + - green.png + code: | + var img = document.getElementById('green.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 50, 50); + + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + + ctx.fillStyle = pattern; + ctx.translate(50, 0); + ctx.fillRect(-50, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.norepeat.coord3 + testing: + - 2d.pattern.painting + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 25); + ctx.fillRect(-50, -25, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeat.basic + testing: + - 2d.pattern.painting + images: + - green-16x16.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('green-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeat.outside + testing: + - 2d.pattern.painting + images: + - green-16x16.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('green-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 25); + ctx.fillRect(-50, -25, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeat.coord1 + testing: + - 2d.pattern.painting + images: + - rgrg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('rgrg-256x256.png'); + var pattern = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = pattern; + ctx.translate(-128, -78); + ctx.fillRect(128, 78, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeat.coord2 + testing: + - 2d.pattern.painting + images: + - ggrr-256x256.png + code: | + var img = document.getElementById('ggrr-256x256.png'); + var pattern = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeat.coord3 + testing: + - 2d.pattern.painting + images: + - rgrg-256x256.png + code: | + var img = document.getElementById('rgrg-256x256.png'); + var pattern = ctx.createPattern(img, 'repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(-128, -78); + ctx.fillRect(128, 78, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeatx.basic + testing: + - 2d.pattern.painting + images: + - green-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 16); + + var img = document.getElementById('green-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeatx.outside + testing: + - 2d.pattern.painting + images: + - red-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 16); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeatx.coord1 + testing: + - 2d.pattern.painting + images: + - red-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.translate(0, 16); + ctx.fillRect(0, -16, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 16); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeaty.basic + testing: + - 2d.pattern.painting + images: + - green-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 16, 50); + + var img = document.getElementById('green-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeaty.outside + testing: + - 2d.pattern.painting + images: + - red-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.repeaty.coord1 + testing: + - 2d.pattern.painting + images: + - red-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('red-16x16.png'); + var pattern = ctx.createPattern(img, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.translate(48, 0); + ctx.fillRect(-48, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 50); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.orientation.image + desc: Image patterns do not get flipped when painted + testing: + - 2d.pattern.painting + images: + - rrgg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var img = document.getElementById('rrgg-256x256.png'); + var pattern = ctx.createPattern(img, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.save(); + ctx.translate(0, -103); + ctx.fillRect(0, 103, 100, 50); + ctx.restore(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 25); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.pattern.paint.orientation.canvas + desc: Canvas patterns do not get flipped when painted + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 25); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 25, 100, 25); + + var pattern = ctx.createPattern(canvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 25); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + + +- name: 2d.pattern.animated.gif + desc: createPattern() of an animated GIF draws the first frame + testing: + - 2d.pattern.animated.image + images: + - anim-gr.gif + code: | + deferTest(); + step_timeout(function () { + var pattern = ctx.createPattern(document.getElementById('anim-gr.gif'), 'repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 50, 50); + step_timeout(t.step_func_done(function () { + ctx.fillRect(50, 0, 50, 50); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 250); + }, 250); + expected: green + + + + +- name: 2d.line.defaults + testing: + - 2d.lineWidth.default + - 2d.lineCap.default + - 2d.lineJoin.default + - 2d.miterLimit.default + code: | + @assert ctx.lineWidth === 1; + @assert ctx.lineCap === 'butt'; + @assert ctx.lineJoin === 'miter'; + @assert ctx.miterLimit === 10; + +- name: 2d.line.width.basic + desc: lineWidth determines the width of line strokes + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 20; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + + @assert pixel 14,25 == 0,255,0,255; + @assert pixel 15,25 == 0,255,0,255; + @assert pixel 16,25 == 0,255,0,255; + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 34,25 == 0,255,0,255; + @assert pixel 35,25 == 0,255,0,255; + @assert pixel 36,25 == 0,255,0,255; + + @assert pixel 64,25 == 0,255,0,255; + @assert pixel 65,25 == 0,255,0,255; + @assert pixel 66,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 84,25 == 0,255,0,255; + @assert pixel 85,25 == 0,255,0,255; + @assert pixel 86,25 == 0,255,0,255; + expected: green + +- name: 2d.line.width.transformed + desc: Line stroke widths are affected by scale transformations + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 4; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.save(); + ctx.scale(5, 1); + ctx.beginPath(); + ctx.moveTo(5, 15); + ctx.lineTo(5, 35); + ctx.stroke(); + ctx.restore(); + + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.save(); + ctx.scale(-5, 1); + ctx.beginPath(); + ctx.moveTo(-15, 15); + ctx.lineTo(-15, 35); + ctx.stroke(); + ctx.restore(); + ctx.fillRect(65, 15, 20, 20); + + @assert pixel 14,25 == 0,255,0,255; + @assert pixel 15,25 == 0,255,0,255; + @assert pixel 16,25 == 0,255,0,255; + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 34,25 == 0,255,0,255; + @assert pixel 35,25 == 0,255,0,255; + @assert pixel 36,25 == 0,255,0,255; + + @assert pixel 64,25 == 0,255,0,255; + @assert pixel 65,25 == 0,255,0,255; + @assert pixel 66,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 84,25 == 0,255,0,255; + @assert pixel 85,25 == 0,255,0,255; + @assert pixel 86,25 == 0,255,0,255; + expected: green + +- name: 2d.line.width.scaledefault + desc: Default lineWidth strokes are affected by scale transformations + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(50, 50); + ctx.strokeStyle = '#0f0'; + ctx.moveTo(0, 0.5); + ctx.lineTo(2, 0.5); + ctx.stroke(); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 50,5 == 0,255,0,255; + @assert pixel 50,45 == 0,255,0,255; + expected: green + +- name: 2d.line.width.valid + desc: Setting lineWidth to valid values works + testing: + - 2d.lineWidth.set + - 2d.lineWidth.get + code: | + ctx.lineWidth = 1.5; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = "1e1"; + @assert ctx.lineWidth === 10; + + ctx.lineWidth = 1/1024; + @assert ctx.lineWidth === 1/1024; + + ctx.lineWidth = 1000; + @assert ctx.lineWidth === 1000; + +- name: 2d.line.width.invalid + desc: Setting lineWidth to invalid values is ignored + testing: + - 2d.lineWidth.invalid + code: | + ctx.lineWidth = 1.5; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = 1.5; + ctx.lineWidth = 0; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = 1.5; + ctx.lineWidth = -1; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = 1.5; + ctx.lineWidth = Infinity; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = 1.5; + ctx.lineWidth = -Infinity; + @assert ctx.lineWidth === 1.5; + + ctx.lineWidth = 1.5; + ctx.lineWidth = NaN; + @assert ctx.lineWidth === 1.5; + +- name: 2d.line.cap.butt + desc: lineCap 'butt' is rendered correctly + testing: + - 2d.lineCap.butt + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineCap = 'butt'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + + @assert pixel 25,14 == 0,255,0,255; + @assert pixel 25,15 == 0,255,0,255; + @assert pixel 25,16 == 0,255,0,255; + @assert pixel 25,34 == 0,255,0,255; + @assert pixel 25,35 == 0,255,0,255; + @assert pixel 25,36 == 0,255,0,255; + + @assert pixel 75,14 == 0,255,0,255; + @assert pixel 75,15 == 0,255,0,255; + @assert pixel 75,16 == 0,255,0,255; + @assert pixel 75,34 == 0,255,0,255; + @assert pixel 75,35 == 0,255,0,255; + @assert pixel 75,36 == 0,255,0,255; + expected: green + +- name: 2d.line.cap.round + desc: lineCap 'round' is rendered correctly + testing: + - 2d.lineCap.round + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineCap = 'round'; + ctx.lineWidth = 20; + + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.beginPath(); + ctx.moveTo(35-tol, 15); + ctx.arc(25, 15, 10-tol, 0, Math.PI, true); + ctx.arc(25, 35, 10-tol, Math.PI, 0, true); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(85+tol, 15); + ctx.arc(75, 15, 10+tol, 0, Math.PI, true); + ctx.arc(75, 35, 10+tol, Math.PI, 0, true); + ctx.fill(); + + @assert pixel 17,6 == 0,255,0,255; + @assert pixel 25,6 == 0,255,0,255; + @assert pixel 32,6 == 0,255,0,255; + @assert pixel 17,43 == 0,255,0,255; + @assert pixel 25,43 == 0,255,0,255; + @assert pixel 32,43 == 0,255,0,255; + + @assert pixel 67,6 == 0,255,0,255; + @assert pixel 75,6 == 0,255,0,255; + @assert pixel 82,6 == 0,255,0,255; + @assert pixel 67,43 == 0,255,0,255; + @assert pixel 75,43 == 0,255,0,255; + @assert pixel 82,43 == 0,255,0,255; + expected: green + +- name: 2d.line.cap.square + desc: lineCap 'square' is rendered correctly + testing: + - 2d.lineCap.square + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineCap = 'square'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 5, 20, 40); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 5, 20, 40); + + @assert pixel 25,4 == 0,255,0,255; + @assert pixel 25,5 == 0,255,0,255; + @assert pixel 25,6 == 0,255,0,255; + @assert pixel 25,44 == 0,255,0,255; + @assert pixel 25,45 == 0,255,0,255; + @assert pixel 25,46 == 0,255,0,255; + + @assert pixel 75,4 == 0,255,0,255; + @assert pixel 75,5 == 0,255,0,255; + @assert pixel 75,6 == 0,255,0,255; + @assert pixel 75,44 == 0,255,0,255; + @assert pixel 75,45 == 0,255,0,255; + @assert pixel 75,46 == 0,255,0,255; + expected: green + +- name: 2d.line.cap.open + desc: Line caps are drawn at the corners of an unclosed rectangle + testing: + - 2d.lineCap.end + code: | + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.lineTo(200, 200); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.cap.closed + desc: Line caps are not drawn at the corners of an unclosed rectangle + testing: + - 2d.lineCap.end + code: | + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.closePath(); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.cap.valid + desc: Setting lineCap to valid values works + testing: + - 2d.lineCap.set + - 2d.lineCap.get + code: | + ctx.lineCap = 'butt' + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'round'; + @assert ctx.lineCap === 'round'; + + ctx.lineCap = 'square'; + @assert ctx.lineCap === 'square'; + +- name: 2d.line.cap.invalid + desc: Setting lineCap to invalid values is ignored + testing: + - 2d.lineCap.invalid + code: | + ctx.lineCap = 'butt' + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = 'invalid'; + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = 'ROUND'; + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = 'round\0'; + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = 'round '; + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = ""; + @assert ctx.lineCap === 'butt'; + + ctx.lineCap = 'butt'; + ctx.lineCap = 'bevel'; + @assert ctx.lineCap === 'butt'; + +- name: 2d.line.join.bevel + desc: lineJoin 'bevel' is rendered correctly + testing: + - 2d.lineJoin.common + - 2d.lineJoin.bevel + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineJoin = 'bevel'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.lineTo(40-tol, 20); + ctx.lineTo(30, 10+tol); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.lineTo(90+tol, 20); + ctx.lineTo(80, 10-tol); + ctx.fill(); + + @assert pixel 34,16 == 0,255,0,255; + @assert pixel 34,15 == 0,255,0,255; + @assert pixel 35,15 == 0,255,0,255; + @assert pixel 36,15 == 0,255,0,255; + @assert pixel 36,14 == 0,255,0,255; + + @assert pixel 84,16 == 0,255,0,255; + @assert pixel 84,15 == 0,255,0,255; + @assert pixel 85,15 == 0,255,0,255; + @assert pixel 86,15 == 0,255,0,255; + @assert pixel 86,14 == 0,255,0,255; + expected: green + +- name: 2d.line.join.round + desc: lineJoin 'round' is rendered correctly + testing: + - 2d.lineJoin.round + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineJoin = 'round'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true); + ctx.fill(); + + @assert pixel 36,14 == 0,255,0,255; + @assert pixel 36,13 == 0,255,0,255; + @assert pixel 37,13 == 0,255,0,255; + @assert pixel 38,13 == 0,255,0,255; + @assert pixel 38,12 == 0,255,0,255; + + @assert pixel 86,14 == 0,255,0,255; + @assert pixel 86,13 == 0,255,0,255; + @assert pixel 87,13 == 0,255,0,255; + @assert pixel 88,13 == 0,255,0,255; + @assert pixel 88,12 == 0,255,0,255; + expected: green + +- name: 2d.line.join.miter + desc: lineJoin 'miter' is rendered correctly + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 30, 20); + ctx.fillRect(20, 10, 20, 30); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 30, 20); + ctx.fillRect(70, 10, 20, 30); + + @assert pixel 38,12 == 0,255,0,255; + @assert pixel 39,11 == 0,255,0,255; + @assert pixel 40,10 == 0,255,0,255; + @assert pixel 41,9 == 0,255,0,255; + @assert pixel 42,8 == 0,255,0,255; + + @assert pixel 88,12 == 0,255,0,255; + @assert pixel 89,11 == 0,255,0,255; + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 91,9 == 0,255,0,255; + @assert pixel 92,8 == 0,255,0,255; + expected: green + +- name: 2d.line.join.open + desc: Line joins are not drawn at the corner of an unclosed rectangle + testing: + - 2d.lineJoin.joins + code: | + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.lineTo(100, 50); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.join.closed + desc: Line joins are drawn at the corner of a closed rectangle + testing: + - 2d.lineJoin.joinclosed + code: | + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.closePath(); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.join.parallel + desc: Line joins are drawn at 180-degree joins + testing: + - 2d.lineJoin.joins + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 300; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.lineTo(0, 25); + ctx.lineTo(-100, 25); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.join.valid + desc: Setting lineJoin to valid values works + testing: + - 2d.lineJoin.set + - 2d.lineJoin.get + code: | + ctx.lineJoin = 'bevel' + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'round'; + @assert ctx.lineJoin === 'round'; + + ctx.lineJoin = 'miter'; + @assert ctx.lineJoin === 'miter'; + +- name: 2d.line.join.invalid + desc: Setting lineJoin to invalid values is ignored + testing: + - 2d.lineJoin.invalid + code: | + ctx.lineJoin = 'bevel' + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'invalid'; + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'ROUND'; + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round\0'; + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round '; + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = ""; + @assert ctx.lineJoin === 'bevel'; + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'butt'; + @assert ctx.lineJoin === 'bevel'; + +- name: 2d.line.miter.exceeded + desc: Miter joins are not drawn when the miter limit is exceeded + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.acute + desc: Miter joins are drawn correctly with acute angles + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 2.614; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 2.613; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.obtuse + desc: Miter joins are drawn correctly with obtuse angles + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 1600; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.083; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.082; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.rightangle + desc: Miter joins are not drawn when the miter limit is exceeded, on exact right angles + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 200); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.lineedge + desc: Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.strokeRect(100, 25, 200, 0); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.within + desc: Miter joins are drawn when the miter limit is not quite exceeded + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.416; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.miter.valid + desc: Setting miterLimit to valid values works + testing: + - 2d.miterLimit.set + - 2d.miterLimit.get + code: | + ctx.miterLimit = 1.5; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = "1e1"; + @assert ctx.miterLimit === 10; + + ctx.miterLimit = 1/1024; + @assert ctx.miterLimit === 1/1024; + + ctx.miterLimit = 1000; + @assert ctx.miterLimit === 1000; + +- name: 2d.line.miter.invalid + desc: Setting miterLimit to invalid values is ignored + testing: + - 2d.miterLimit.invalid + code: | + ctx.miterLimit = 1.5; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = 1.5; + ctx.miterLimit = 0; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = 1.5; + ctx.miterLimit = -1; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = 1.5; + ctx.miterLimit = Infinity; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = 1.5; + ctx.miterLimit = -Infinity; + @assert ctx.miterLimit === 1.5; + + ctx.miterLimit = 1.5; + ctx.miterLimit = NaN; + @assert ctx.miterLimit === 1.5; + +- name: 2d.line.cross + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'bevel'; + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(110, 50); + ctx.lineTo(110, 60); + ctx.lineTo(100, 60); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + expected: green + +- name: 2d.line.union + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 24); + ctx.lineTo(100, 25); + ctx.lineTo(0, 26); + ctx.closePath(); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 25,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 25,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + expected: green + + + + + + + +- name: 2d.shadow.attributes.shadowBlur.initial + testing: + - 2d.shadow.blur.get + - 2d.shadow.blur.initial + code: | + @assert ctx.shadowBlur === 0; + +- name: 2d.shadow.attributes.shadowBlur.valid + testing: + - 2d.shadow.blur.get + - 2d.shadow.blur.set + code: | + ctx.shadowBlur = 1; + @assert ctx.shadowBlur === 1; + + ctx.shadowBlur = 0.5; + @assert ctx.shadowBlur === 0.5; + + ctx.shadowBlur = 1e6; + @assert ctx.shadowBlur === 1e6; + + ctx.shadowBlur = 0; + @assert ctx.shadowBlur === 0; + +- name: 2d.shadow.attributes.shadowBlur.invalid + testing: + - 2d.shadow.blur.invalid + code: | + ctx.shadowBlur = 1; + ctx.shadowBlur = -2; + @assert ctx.shadowBlur === 1; + + ctx.shadowBlur = 1; + ctx.shadowBlur = Infinity; + @assert ctx.shadowBlur === 1; + + ctx.shadowBlur = 1; + ctx.shadowBlur = -Infinity; + @assert ctx.shadowBlur === 1; + + ctx.shadowBlur = 1; + ctx.shadowBlur = NaN; + @assert ctx.shadowBlur === 1; + +- name: 2d.shadow.attributes.shadowOffset.initial + testing: + - 2d.shadow.offset.initial + code: | + @assert ctx.shadowOffsetX === 0; + @assert ctx.shadowOffsetY === 0; + +- name: 2d.shadow.attributes.shadowOffset.valid + testing: + - 2d.shadow.offset.get + - 2d.shadow.offset.set + code: | + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + + ctx.shadowOffsetX = 0.5; + ctx.shadowOffsetY = 0.25; + @assert ctx.shadowOffsetX === 0.5; + @assert ctx.shadowOffsetY === 0.25; + + ctx.shadowOffsetX = -0.5; + ctx.shadowOffsetY = -0.25; + @assert ctx.shadowOffsetX === -0.5; + @assert ctx.shadowOffsetY === -0.25; + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + @assert ctx.shadowOffsetX === 0; + @assert ctx.shadowOffsetY === 0; + + ctx.shadowOffsetX = 1e6; + ctx.shadowOffsetY = 1e6; + @assert ctx.shadowOffsetX === 1e6; + @assert ctx.shadowOffsetY === 1e6; + +- name: 2d.shadow.attributes.shadowOffset.invalid + testing: + - 2d.shadow.offset.invalid + code: | + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = Infinity; + ctx.shadowOffsetY = Infinity; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = -Infinity; + ctx.shadowOffsetY = -Infinity; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = NaN; + ctx.shadowOffsetY = NaN; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + +- name: 2d.shadow.attributes.shadowColor.initial + testing: + - 2d.shadow.color.initial + code: | + @assert ctx.shadowColor === 'rgba(0, 0, 0, 0)'; + +- name: 2d.shadow.attributes.shadowColor.valid + testing: + - 2d.shadow.color.get + - 2d.shadow.color.set + code: | + ctx.shadowColor = 'lime'; + @assert ctx.shadowColor === '#00ff00'; + + ctx.shadowColor = 'RGBA(0,255, 0,0)'; + @assert ctx.shadowColor === 'rgba(0, 255, 0, 0)'; + +- name: 2d.shadow.attributes.shadowColor.invalid + testing: + - 2d.shadow.color.invalid + code: | + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = 'bogus'; + @assert ctx.shadowColor === '#00ff00'; + + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = 'red bogus'; + @assert ctx.shadowColor === '#00ff00'; + + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = ctx; + @assert ctx.shadowColor === '#00ff00'; + + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = undefined; + @assert ctx.shadowColor === '#00ff00'; + +- name: 2d.shadow.enable.off.1 + desc: Shadows are not drawn when only shadowColor is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.shadowColor = '#f00'; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.enable.off.2 + desc: Shadows are not drawn when only shadowColor is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.enable.blur + desc: Shadows are drawn if shadowBlur is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.enable.x + desc: Shadows are drawn if shadowOffsetX is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.enable.y + desc: Shadows are drawn if shadowOffsetY is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.offset.positiveX + desc: Shadows can be offset with positive x + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.offset.negativeX + desc: Shadows can be offset with negative x + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = -50; + ctx.fillRect(50, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.offset.positiveY + desc: Shadows can be offset with positive y + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 25; + ctx.fillRect(0, 0, 100, 25); + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + expected: green + +- name: 2d.shadow.offset.negativeY + desc: Shadows can be offset with negative y + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = -25; + ctx.fillRect(0, 25, 100, 25); + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + expected: green + +- name: 2d.shadow.outside + desc: Shadows of shapes outside the visible area can be offset onto the visible area + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 100; + ctx.fillRect(-100, 0, 25, 50); + ctx.shadowOffsetX = -100; + ctx.fillRect(175, 0, 25, 50); + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 100; + ctx.fillRect(25, -100, 50, 25); + ctx.shadowOffsetY = -100; + ctx.fillRect(25, 125, 50, 25); + @assert pixel 12,25 == 0,255,0,255; + @assert pixel 87,25 == 0,255,0,255; + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + expected: green + +- name: 2d.shadow.clip.1 + desc: Shadows of clipped shapes are still drawn within the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + + ctx.save(); + ctx.beginPath(); + ctx.rect(50, 0, 50, 50); + ctx.clip(); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + ctx.restore(); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.clip.2 + desc: Shadows are not drawn outside the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + ctx.restore(); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.clip.3 + desc: Shadows of clipped shapes are still drawn within the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(-50, 0, 50, 50); + ctx.restore(); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.basic + desc: Shadows are drawn for strokes + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.moveTo(0, -25); + ctx.lineTo(100, -25); + ctx.stroke(); + + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.cap.1 + desc: Shadows are not drawn for areas outside stroke caps + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.lineCap = 'butt'; + ctx.moveTo(-50, -25); + ctx.lineTo(0, -25); + ctx.moveTo(100, -25); + ctx.lineTo(150, -25); + ctx.stroke(); + + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.cap.2 + desc: Shadows are drawn for stroke caps + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.lineCap = 'square'; + ctx.moveTo(25, -25); + ctx.lineTo(75, -25); + ctx.stroke(); + + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.join.1 + desc: Shadows are not drawn for areas outside stroke joins + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'bevel'; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.join.2 + desc: Shadows are drawn for stroke joins + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.shadow.stroke.join.3 + desc: Shadows are drawn for stroke joins respecting miter limit + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 0.1; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3) + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.shadow.image.basic + desc: Shadows are drawn for images + testing: + - 2d.shadow.render + images: + - red.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.drawImage(document.getElementById('red.png'), 0, -50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.image.transparent.1 + desc: Shadows are not drawn for transparent images + testing: + - 2d.shadow.render + images: + - transparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.drawImage(document.getElementById('transparent.png'), 0, -50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.image.transparent.2 + desc: Shadows are not drawn for transparent parts of images + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.drawImage(document.getElementById('redtransparent.png'), 50, -50); + ctx.shadowColor = '#f00'; + ctx.drawImage(document.getElementById('redtransparent.png'), -50, -50); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.image.alpha + desc: Shadows are drawn correctly for partially-transparent images + testing: + - 2d.shadow.render + images: + - transparent50.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.drawImage(document.getElementById('transparent50.png'), 0, -50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.image.section + desc: Shadows are not drawn for areas outside image source rectangles + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#f00'; + ctx.drawImage(document.getElementById('redtransparent.png'), 50, 0, 50, 50, 0, -50, 50, 50); + + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.shadow.image.scale + desc: Shadows are drawn correctly for scaled images + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.drawImage(document.getElementById('redtransparent.png'), 0, 0, 100, 50, -10, -50, 240, 50); + + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.shadow.canvas.basic + desc: Shadows are drawn for canvases + testing: + - 2d.shadow.render + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.drawImage(canvas2, 0, -50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.canvas.transparent.1 + desc: Shadows are not drawn for transparent canvases + testing: + - 2d.shadow.render + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.drawImage(canvas2, 0, -50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.canvas.transparent.2 + desc: Shadows are not drawn for transparent parts of canvases + testing: + - 2d.shadow.render + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 50, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.drawImage(canvas2, 50, -50); + ctx.shadowColor = '#f00'; + ctx.drawImage(canvas2, -50, -50); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.canvas.alpha + desc: Shadows are drawn correctly for partially-transparent canvases + testing: + - 2d.shadow.render + images: + - transparent50.png + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.drawImage(canvas2, 0, -50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.pattern.basic + desc: Shadows are drawn for fill patterns + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + images: + - red.png + code: | + var pattern = ctx.createPattern(document.getElementById('red.png'), 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.pattern.transparent.1 + desc: Shadows are not drawn for transparent fill patterns + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + images: + - transparent.png + code: | + var pattern = ctx.createPattern(document.getElementById('transparent.png'), 'repeat'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.pattern.transparent.2 + desc: Shadows are not drawn for transparent parts of fill patterns + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + images: + - redtransparent.png + code: | + var pattern = ctx.createPattern(document.getElementById('redtransparent.png'), 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.pattern.alpha + desc: Shadows are drawn correctly for partially-transparent fill patterns + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + images: + - transparent50.png + code: | + var pattern = ctx.createPattern(document.getElementById('transparent50.png'), 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.gradient.basic + desc: Shadows are drawn for gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, '#f00'); + gradient.addColorStop(1, '#f00'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.gradient.transparent.1 + desc: Shadows are not drawn for transparent gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, 'rgba(0,0,0,0)'); + gradient.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.gradient.transparent.2 + desc: Shadows are not drawn for transparent parts of gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, '#f00'); + gradient.addColorStop(0.499, '#f00'); + gradient.addColorStop(0.5, 'rgba(0,0,0,0)'); + gradient.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.gradient.alpha + desc: Shadows are drawn correctly for partially-transparent gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, 'rgba(255,0,0,0.5)'); + gradient.addColorStop(1, 'rgba(255,0,0,0.5)'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.transform.1 + desc: Shadows take account of transformations + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.translate(100, 100); + ctx.fillRect(-100, -150, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.transform.2 + desc: Shadow offsets are not affected by transformations + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.rotate(Math.PI) + ctx.fillRect(-100, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.shadow.blur.low + desc: Shadows look correct for small blurs + manual: + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 25; + for (var x = 0; x < 100; ++x) { + ctx.save(); + ctx.beginPath(); + ctx.rect(x, 0, 1, 50); + ctx.clip(); + ctx.shadowBlur = x; + ctx.fillRect(-200, -200, 500, 200); + ctx.restore(); + } + expected: | + size 100 50 + import math + cr.set_source_rgb(0, 0, 1) + cr.rectangle(0, 0, 1, 25) + cr.fill() + cr.set_source_rgb(1, 1, 0) + cr.rectangle(0, 25, 1, 25) + cr.fill() + for x in range(1, 100): + sigma = x/2.0 + filter = [math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma) for i in range(-24, 26)] + accum = [0] + for f in filter: + accum.append(accum[-1] + f) + for y in range(0, 50): + cr.set_source_rgb(accum[y], accum[y], 1-accum[y]) + cr.rectangle(x, y, 1, 1) + cr.fill() + +- name: 2d.shadow.blur.high + desc: Shadows look correct for large blurs + manual: + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 100; + ctx.fillRect(-200, -200, 200, 400); + expected: | + size 100 50 + import math + sigma = 100.0/2 + filter = [math.exp(-i*i / (2*sigma*sigma)) / (math.sqrt(2*math.pi)*sigma) for i in range(-200, 100)] + accum = [0] + for f in filter: + accum.append(accum[-1] + f) + for x in range(0, 100): + cr.set_source_rgb(accum[x+200], accum[x+200], 1-accum[x+200]) + cr.rectangle(x, 0, 1, 50) + cr.fill() + +- name: 2d.shadow.alpha.1 + desc: Shadow colour alpha components are used + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = 'rgba(255, 0, 0, 0.01)'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 0,255,0,255 +/- 4; + expected: green + +- name: 2d.shadow.alpha.2 + desc: Shadow colour alpha components are used + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = 'rgba(0, 0, 255, 0.5)'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.alpha.3 + desc: Shadows are affected by globalAlpha + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 50; + ctx.globalAlpha = 0.5; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.alpha.4 + desc: Shadows with alpha components are correctly affected by globalAlpha + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) + ctx.shadowColor = 'rgba(0, 0, 255, 0.707)'; + ctx.shadowOffsetY = 50; + ctx.globalAlpha = 0.707; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.alpha.5 + desc: Shadows of shapes with alpha components are drawn correctly + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = 'rgba(64, 0, 0, 0.5)'; + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + + @assert pixel 50,25 ==~ 127,0,127,255; + expected: | + size 100 50 + cr.set_source_rgb(0.5, 0, 0.5) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.shadow.composite.1 + desc: Shadows are drawn using globalCompositeOperation + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, 0, 200, 50); + + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.shadow.composite.2 + desc: Shadows are drawn using globalCompositeOperation + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 1; + ctx.fillStyle = '#0f0'; + ctx.fillRect(-10, -10, 120, 70); + + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.shadow.composite.3 + desc: Areas outside shadows are drawn correctly with destination-out + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-out'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 10; + ctx.fillStyle = '#f00'; + ctx.fillRect(200, 0, 100, 50); + + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + + + + + + +- name: 2d.clearRect.basic + desc: clearRect clears to transparent black + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.clearRect.path + desc: clearRect does not affect the current path + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clearRect(0, 0, 16, 16); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.clearRect.zero + desc: clearRect of zero pixels has no effect + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 100, 0); + ctx.clearRect(0, 0, 0, 50); + ctx.clearRect(0, 0, 0, 0); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.clearRect.negative + desc: clearRect of negative sizes works + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 50, 25); + ctx.clearRect(100, 0, -50, 25); + ctx.clearRect(0, 50, 50, -25); + ctx.clearRect(100, 50, -50, -25); + @assert pixel 25,12 == 0,0,0,0; + @assert pixel 75,12 == 0,0,0,0; + @assert pixel 25,37 == 0,0,0,0; + @assert pixel 75,37 == 0,0,0,0; + expected: clear + +- name: 2d.clearRect.transform + desc: clearRect is affected by transforms + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.clearRect(0, -5, 10, 5); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.clearRect.globalalpha + desc: clearRect is not affected by globalAlpha + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.1; + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.clearRect.globalcomposite + desc: clearRect is not affected by globalCompositeOperation + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-atop'; + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.clearRect.clip + desc: clearRect is affected by clipping regions + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + + ctx.clearRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.clearRect.shadow + desc: clearRect does not draw shadows + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.clearRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.clearRect.nonfinite + desc: clearRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + @nonfinite ctx.clearRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.fillRect.basic + desc: fillRect works + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.path + desc: fillRect does not affect the current path + testing: + - 2d.fillRect + code: | + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.zero + desc: fillRect of zero pixels has no effect + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 0); + ctx.fillRect(0, 0, 0, 50); + ctx.fillRect(0, 0, 0, 0); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.negative + desc: fillRect of negative sizes works + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + ctx.fillRect(100, 0, -50, 25); + ctx.fillRect(0, 50, 50, -25); + ctx.fillRect(100, 50, -50, -25); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.transform + desc: fillRect is affected by transforms + testing: + - 2d.fillRect + code: | + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -5, 10, 5); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +# don't bother testing globalalpha, globalcomposite because they're already heavily used by other test cases + +- name: 2d.fillRect.clip + desc: fillRect is affected by clipping regions + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.shadow + desc: fillRect draws shadows + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.fillRect.nonfinite + desc: fillRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + @nonfinite ctx.fillRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.strokeRect.basic + desc: strokeRect works + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.path + desc: strokeRect does not affect the current path + testing: + - 2d.strokeRect + code: | + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 5; + ctx.strokeRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.zero.1 + desc: strokeRect of 0x0 pixels draws nothing + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.strokeRect(50, 25, 0, 0); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.strokeRect.zero.2 + desc: strokeRect of 0x0 pixels draws nothing, including caps and joins + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.strokeRect(50, 25, 0, 0); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.strokeRect.zero.3 + desc: strokeRect of Nx0 pixels draws a straight line + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.strokeRect(0, 25, 100, 0); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.zero.4 + desc: strokeRect of Nx0 pixels draws a closed line with no caps + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.lineCap = 'round'; + ctx.strokeRect(100, 25, 100, 0); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.strokeRect.zero.5 + desc: strokeRect of Nx0 pixels draws a closed line with joins + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 250; + ctx.lineJoin = 'round'; + ctx.strokeRect(100, 25, 100, 0); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.negative + desc: strokeRect of negative sizes works + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 25; + ctx.strokeRect(12, 12, 26, 1); + ctx.strokeRect(88, 12, -26, 1); + ctx.strokeRect(12, 38, 26, -1); + ctx.strokeRect(88, 38, -26, -1); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.transform + desc: fillRect is affected by transforms + testing: + - 2d.strokeRect + code: | + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 5; + ctx.strokeRect(2.5, -2.6, 5, 0.2); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.globalalpha + desc: strokeRect is affected by globalAlpha + testing: + - 2d.strokeRect + code: | + ctx.globalAlpha = 0; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.strokeRect.globalcomposite + desc: strokeRect is not affected by globalCompositeOperation + testing: + - 2d.strokeRect + code: | + ctx.globalCompositeOperation = 'source-in'; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,0,0,0; + expected: clear + +- name: 2d.strokeRect.clip + desc: strokeRect is affected by clipping regions + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.shadow + desc: strokeRect draws shadows + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(0, -75, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.strokeRect.nonfinite + desc: strokeRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 150; + @nonfinite ctx.strokeRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.path.initial + testing: + - 2d.path.initial + #mozilla: { bug: TODO } + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.beginPath + testing: + - 2d.path.beginPath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.moveTo.basic + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 10, 50); + ctx.moveTo(100, 0); + ctx.lineTo(10, 0); + ctx.lineTo(10, 50); + ctx.lineTo(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 90,25 == 0,255,0,255; + expected: green + +- name: 2d.path.moveTo.newsubpath + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.moveTo(100, 0); + ctx.moveTo(100, 50); + ctx.moveTo(0, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.moveTo.multiple + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 25); + ctx.moveTo(100, 25); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.moveTo.nonfinite + desc: moveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.moveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.closePath.empty + testing: + - 2d.path.closePath.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.closePath.newline + testing: + - 2d.path.closePath.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.closePath(); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.closePath.nextpoint + testing: + - 2d.path.closePath.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -1000); + ctx.closePath(); + ctx.lineTo(1000, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.ensuresubpath.1 + desc: If there is no subpath, the point is added and nothing is drawn + testing: + - 2d.path.lineTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(100, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.ensuresubpath.2 + desc: If there is no subpath, the point is added and used for subsequent drawing + testing: + - 2d.path.lineTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.basic + testing: + - 2d.path.lineTo.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.nextpoint + testing: + - 2d.path.lineTo.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.nonfinite + desc: lineTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.lineTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + +- name: 2d.path.lineTo.nonfinite.details + desc: lineTo() with Infinity/NaN for first arg still converts the second arg + testing: + - 2d.nonfinite + code: | + for (var arg1 of [Infinity, -Infinity, NaN]) { + var converted = false; + ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } }); + @assert converted; + } + expected: clear + +- name: 2d.path.quadraticCurveTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.quadratic.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(100, 50, 200, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 95,45 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.quadraticCurveTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.quadratic.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(0, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.quadraticCurveTo.basic + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.quadraticCurveTo(100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.quadraticCurveTo.shape + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-1000, 1050); + ctx.quadraticCurveTo(0, -1000, 1200, 1050); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.quadraticCurveTo.scaled + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-1, 1.05); + ctx.quadraticCurveTo(0, -1, 1.2, 1.05); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.quadraticCurveTo.nonfinite + desc: quadraticCurveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.quadraticCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.bezier.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(100, 50, 200, 50, 200, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 95,45 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.bezier.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(0, 25, 100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.basic + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.bezierCurveTo(100, 25, 100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.shape + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-2000, 3100); + ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.scaled + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-2, 3.1); + ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.bezierCurveTo.nonfinite + desc: bezierCurveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.bezierCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.arcTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arcTo(100, 50, 200, 50, 0.1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.arcTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.coincide.1 + desc: arcTo() has no effect if P0 = P1 + testing: + - 2d.path.arcTo.coincide.01 + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(0, 25, 50, 1000, 1); + ctx.lineTo(100, 25); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 100, 25, 1); + ctx.stroke(); + + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.coincide.2 + desc: arcTo() draws a straight line to P1 if P1 = P2 + testing: + - 2d.path.arcTo.coincide.12 + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 25, 1); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.collinear.1 + desc: arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 200, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, 100, 25, 1); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.collinear.2 + desc: arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 10, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 110, 25, 1); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.collinear.3 + desc: arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 0, 25, 1); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, -200, 25, 1); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.shape.curve1 + desc: arcTo() curves in the right kind of shape + testing: + - 2d.path.arcTo.shape + code: | + var tol = 1.5; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 55,19 == 0,255,0,255; + @assert pixel 55,20 == 0,255,0,255; + @assert pixel 55,21 == 0,255,0,255; + @assert pixel 64,22 == 0,255,0,255; + @assert pixel 65,21 == 0,255,0,255; + @assert pixel 72,28 == 0,255,0,255; + @assert pixel 73,27 == 0,255,0,255; + @assert pixel 78,36 == 0,255,0,255; + @assert pixel 79,35 == 0,255,0,255; + @assert pixel 80,44 == 0,255,0,255; + @assert pixel 80,45 == 0,255,0,255; + @assert pixel 80,46 == 0,255,0,255; + @assert pixel 65,45 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.shape.curve2 + desc: arcTo() curves in the right kind of shape + testing: + - 2d.path.arcTo.shape + code: | + var tol = 1.5; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false); + ctx.fill(); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 55,19 == 0,255,0,255; + @assert pixel 55,20 == 0,255,0,255; + @assert pixel 55,21 == 0,255,0,255; + @assert pixel 64,22 == 0,255,0,255; + @assert pixel 65,21 == 0,255,0,255; + @assert pixel 72,28 == 0,255,0,255; + @assert pixel 73,27 == 0,255,0,255; + @assert pixel 78,36 == 0,255,0,255; + @assert pixel 79,35 == 0,255,0,255; + @assert pixel 80,44 == 0,255,0,255; + @assert pixel 80,45 == 0,255,0,255; + @assert pixel 80,46 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.shape.start + desc: arcTo() draws a straight line from P0 to P1 + testing: + - 2d.path.arcTo.shape + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(200, 25, 200, 50, 10); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.shape.end + desc: arcTo() does not draw anything from P1 to P2 + testing: + - 2d.path.arcTo.shape + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.arcTo(-100, 25, 200, 25, 10); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.negative + desc: arcTo() with negative radius throws an exception + testing: + - 2d.path.arcTo.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.arcTo(0, 0, 0, 0, -1); + +- name: 2d.path.arcTo.zero.1 + desc: arcTo() with zero radius draws a straight line from P0 to P1 + testing: + - 2d.path.arcTo.zeroradius + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 100, 0); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(0, -25); + ctx.arcTo(50, -25, 50, 50, 0); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.zero.2 + desc: arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear + testing: + - 2d.path.arcTo.zeroradius + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 0); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 50, 25, 0); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.transformation + desc: arcTo joins up to the last subpath point correctly + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-100, 0); + ctx.fill(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.scale + desc: arcTo scales the curve, not just the control points + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.scale(0.1, 1); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-1000, 0); + ctx.fill(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.arcTo.nonfinite + desc: arcTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.arcTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + + +- name: 2d.path.arc.empty + desc: arc() with an empty path does not draw a straight line to the start point + testing: + - 2d.path.arc.nonempty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.nonempty + desc: arc() with a non-empty path does draw a straight line to the start point + testing: + - 2d.path.arc.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.end + desc: arc() adds the end point of the arc to the subpath + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(-100, 0); + ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.default + desc: arc() with missing last argument defaults to clockwise + testing: + - 2d.path.arc.omitted + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, -Math.PI, Math.PI/2); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.1 + desc: arc() draws pi/2 .. -pi anticlockwise correctly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.2 + desc: arc() draws -3pi/2 .. -pi anticlockwise correctly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.3 + desc: arc() wraps angles mod 2pi when anticlockwise and end > start+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.4 + desc: arc() draws a full circle when clockwise and end > start+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false); + ctx.fill(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.5 + desc: arc() wraps angles mod 2pi when clockwise and start > end+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.angle.6 + desc: arc() draws a full circle when anticlockwise and start > end+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true); + ctx.fill(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.zero.1 + desc: arc() draws nothing when startAngle = endAngle and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.zero.2 + desc: arc() draws nothing when startAngle = endAngle and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.twopie.1 + desc: arc() draws nothing when end = start + 2pi-e and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.twopie.2 + desc: arc() draws a full circle when end = start + 2pi-e and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.twopie.3 + desc: arc() draws a full circle when end = start + 2pi+e and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.twopie.4 + desc: arc() draws nothing when end = start + 2pi+e and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.shape.1 + desc: arc() from 0 to pi does not draw anything in the wrong half + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 20,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.shape.2 + desc: arc() from 0 to pi draws stuff in the right half + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 20,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.shape.3 + desc: arc() from 0 to -pi/2 does not draw anything in the wrong quadrant + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(0, 50, 50, 0, -Math.PI/2, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.shape.4 + desc: arc() from 0 to -pi/2 draws stuff in the right quadrant + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 150; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 100, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.shape.5 + desc: arc() from 0 to 5pi does not draw crazy things + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(300, 0, 100, 0, 5*Math.PI, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.selfintersect.1 + desc: arc() with lineWidth > 2*radius is drawn sensibly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(100, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(0, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.selfintersect.2 + desc: arc() with lineWidth > 2*radius is drawn sensibly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 180; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(100, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 97,1 == 0,255,0,255; + @assert pixel 97,2 == 0,255,0,255; + @assert pixel 97,3 == 0,255,0,255; + @assert pixel 2,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.negative + desc: arc() with negative radius throws INDEX_SIZE_ERR + testing: + - 2d.path.arc.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.arc(0, 0, -1, 0, 0, true); + +- name: 2d.path.arc.zeroradius + desc: arc() with zero radius draws a line to the start point + testing: + - 2d.path.arc.zero + code: | + ctx.fillStyle = '#f00' + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 0, 0, Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.scale.1 + desc: Non-uniformly scaled arcs are the right shape + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(2, 0.5); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(25, 50, 56, 0, 2*Math.PI, false); + ctx.fill(); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-25, 50); + ctx.arc(-25, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(75, 50); + ctx.arc(75, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, -25); + ctx.arc(25, -25, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, 125); + ctx.arc(25, 125, 24, 0, 2*Math.PI, false); + ctx.fill(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.scale.2 + desc: Highly scaled arcs are the right shape + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(100, 100); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 1.2; + ctx.beginPath(); + ctx.arc(0, 0, 0.6, 0, Math.PI/2, false); + ctx.stroke(); + + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.arc.nonfinite + desc: arc() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.arc(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <2*Math.PI Infinity -Infinity NaN>, <true>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + + +- name: 2d.path.rect.basic + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 100, 50); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.newsubpath + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-50, 25); + ctx.rect(200, 25, 1, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.closed + testing: + - 2d.path.rect.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.rect(100, 50, 100, 100); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.end.1 + testing: + - 2d.path.rect.newsubpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.rect(200, 100, 400, 1000); + ctx.lineTo(-2000, -1000); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.end.2 + testing: + - 2d.path.rect.newsubpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 450; + ctx.lineCap = 'round'; + ctx.lineJoin = 'bevel'; + ctx.rect(150, 150, 2000, 2000); + ctx.lineTo(160, 160); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.1 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(0, 50, 100, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.2 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, -100, 0, 250); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.3 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.4 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.rect(100, 25, 0, 0); + ctx.lineTo(0, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.5 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(0, 0); + ctx.rect(100, 25, 0, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.rect.zero.6 + testing: + - 2d.path.rect.subpath + #mozilla: { bug: TODO } + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.5; + ctx.lineWidth = 200; + ctx.beginPath(); + ctx.rect(100, 25, 1000, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.rect.negative + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 50, 25); + ctx.rect(100, 0, -50, 25); + ctx.rect(0, 50, 50, -25); + ctx.rect(100, 50, -50, -25); + ctx.fill(); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.path.rect.winding + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.rect(0, 0, 50, 50); + ctx.rect(100, 50, -50, -50); + ctx.rect(0, 25, 100, -25); + ctx.rect(100, 25, -100, 25); + ctx.fill(); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.path.rect.selfintersect + #mozilla: { bug: TODO } + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 90; + ctx.beginPath(); + ctx.rect(45, 20, 10, 10); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.rect.nonfinite + desc: rect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.rect(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.overlap + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.rect(0, 0, 100, 50); + ctx.closePath(); + ctx.rect(10, 10, 80, 30); + ctx.fill(); + + @assert pixel 50,25 ==~ 0,127,0,255 +/- 1; + expected: | + size 100 50 + cr.set_source_rgb(0, 0.5, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.path.fill.winding.add + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.winding.subtract.1 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.winding.subtract.2 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.winding.subtract.3 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(-20, -20); + ctx.lineTo(120, -20); + ctx.lineTo(120, 70); + ctx.lineTo(-20, 70); + ctx.lineTo(-20, -20); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.closed.basic + testing: + - 2d.path.fill.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.fill.closed.unaffected + testing: + - 2d.path.fill.closed + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 10,40 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.overlap + desc: Stroked subpaths are combined before being drawn + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.lineWidth = 50; + ctx.moveTo(0, 20); + ctx.lineTo(100, 20); + ctx.moveTo(0, 30); + ctx.lineTo(100, 30); + ctx.stroke(); + + @assert pixel 50,25 ==~ 0,127,0,255 +/- 1; + expected: | + size 100 50 + cr.set_source_rgb(0, 0.5, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.path.stroke.union + desc: Strokes in opposite directions are unioned, not subtracted + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 40; + ctx.moveTo(0, 10); + ctx.lineTo(100, 10); + ctx.moveTo(100, 40); + ctx.lineTo(0, 40); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.unaffected + desc: Stroking does not start a new path or subpath + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + + ctx.closePath(); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.scale1 + desc: Stroke line widths are scaled by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.scale2 + desc: Stroke line widths are scaled by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.skew + desc: Strokes lines are skewed by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.beginPath(); + ctx.moveTo(49, -50); + ctx.lineTo(201, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 283); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.empty + desc: Empty subpaths are not stroked + testing: + - 2d.path.stroke.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(40, 25); + ctx.moveTo(60, 25); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.stroke.prune.line + desc: Zero-length line segments from lineTo are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.stroke.prune.closed + desc: Zero-length line segments from closed paths are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.closePath(); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.stroke.prune.curve + desc: Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.quadraticCurveTo(50, 25, 50, 25); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.stroke.prune.arc + desc: Zero-length line segments from arcTo and arc are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 150, 25, 10); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(60, 25); + ctx.arc(50, 25, 10, 0, 0, false); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.stroke.prune.rect + desc: Zero-length line segments from rect and strokeRect are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + + ctx.strokeRect(50, 25, 0, 0); + + @assert pixel 50,25 == 0,255,0,255; @moz-todo + expected: green + +- name: 2d.path.stroke.prune.corner + desc: Zero-length line segments are removed before stroking with miters + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.4; + + ctx.beginPath(); + ctx.moveTo(-1000, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 1000); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.path.transformation.basic + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(-100, 0); + ctx.rect(100, 0, 100, 50); + ctx.translate(0, -100); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.transformation.multiple + # TODO: change this name + desc: Transformations are applied while building paths, not when drawing + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.translate(-100, 0); + ctx.rect(0, 0, 100, 50); + ctx.fill(); + ctx.translate(100, 0); + ctx.fill(); + + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.translate(0, -50); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + ctx.translate(0, 50); + ctx.stroke(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.transformation.changing + desc: Transformations are applied while building paths, not when drawing + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.translate(100, 0); + ctx.lineTo(0, 0); + ctx.translate(0, 50); + ctx.lineTo(0, 0); + ctx.translate(-100, 0); + ctx.lineTo(0, 0); + ctx.translate(1000, 1000); + ctx.rotate(Math.PI/2); + ctx.scale(0.1, 0.1); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + +- name: 2d.path.clip.empty + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.basic.1 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clip(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.basic.2 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(-100, 0, 100, 50); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.intersect + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.beginPath(); + ctx.rect(50, 0, 50, 50) + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.winding.1 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.winding.2 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.clip(); + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.lineTo(0, 0); + ctx.clip(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.path.clip.unaffected + testing: + - 2d.path.clip.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + + ctx.lineTo(0, 0); + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + expected: green + + + +- name: 2d.path.isPointInPath.basic.1 + desc: isPointInPath() detects whether the point is inside the path + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === true; + @assert ctx.isPointInPath(30, 10) === false; + +- name: 2d.path.isPointInPath.basic.2 + desc: isPointInPath() detects whether the point is inside the path + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(20, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(30, 10) === true; + +- name: 2d.path.isPointInPath.edge + desc: isPointInPath() counts points on the path as being inside + testing: + - 2d.path.isPointInPath.edge + code: | + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(0, 0) === true; + @assert ctx.isPointInPath(10, 0) === true; + @assert ctx.isPointInPath(20, 0) === true; + @assert ctx.isPointInPath(20, 10) === true; + @assert ctx.isPointInPath(20, 20) === true; + @assert ctx.isPointInPath(10, 20) === true; + @assert ctx.isPointInPath(0, 20) === true; + @assert ctx.isPointInPath(0, 10) === true; + @assert ctx.isPointInPath(10, -0.01) === false; + @assert ctx.isPointInPath(10, 20.01) === false; + @assert ctx.isPointInPath(-0.01, 10) === false; + @assert ctx.isPointInPath(20.01, 10) === false; + +- name: 2d.path.isPointInPath.empty + desc: isPointInPath() works when there is no path + testing: + - 2d.path.isPointInPath + code: | + @assert ctx.isPointInPath(0, 0) === false; + +- name: 2d.path.isPointInPath.subpath + desc: isPointInPath() uses the current path, not just the subpath + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, 0, 20, 20); + ctx.beginPath(); + ctx.rect(20, 0, 20, 20); + ctx.closePath(); + ctx.rect(40, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(30, 10) === true; + @assert ctx.isPointInPath(50, 10) === true; + +- name: 2d.path.isPointInPath.outside + desc: isPointInPath() works on paths outside the canvas + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, -100, 20, 20); + ctx.rect(20, -10, 20, 20); + @assert ctx.isPointInPath(10, -110) === false; + @assert ctx.isPointInPath(10, -90) === true; + @assert ctx.isPointInPath(10, -70) === false; + @assert ctx.isPointInPath(30, -20) === false; + @assert ctx.isPointInPath(30, 0) === true; + @assert ctx.isPointInPath(30, 20) === false; + +- name: 2d.path.isPointInPath.unclosed + desc: isPointInPath() works on unclosed subpaths + testing: + - 2d.path.isPointInPath + code: | + ctx.moveTo(0, 0); + ctx.lineTo(20, 0); + ctx.lineTo(20, 20); + ctx.lineTo(0, 20); + @assert ctx.isPointInPath(10, 10) === true; + @assert ctx.isPointInPath(30, 10) === false; + +- name: 2d.path.isPointInPath.arc + desc: isPointInPath() works on arcs + testing: + - 2d.path.isPointInPath + code: | + ctx.arc(50, 25, 10, 0, Math.PI, false); + @assert ctx.isPointInPath(50, 10) === false; + @assert ctx.isPointInPath(50, 20) === false; + @assert ctx.isPointInPath(50, 30) === true; + @assert ctx.isPointInPath(50, 40) === false; + @assert ctx.isPointInPath(30, 20) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(70, 30) === false; + +- name: 2d.path.isPointInPath.bigarc + desc: isPointInPath() works on unclosed arcs larger than 2pi + opera: { bug: 320937 } + testing: + - 2d.path.isPointInPath + code: | + ctx.arc(50, 25, 10, 0, 7, false); + @assert ctx.isPointInPath(50, 10) === false; + @assert ctx.isPointInPath(50, 20) === true; + @assert ctx.isPointInPath(50, 30) === true; + @assert ctx.isPointInPath(50, 40) === false; + @assert ctx.isPointInPath(30, 20) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(70, 30) === false; + +- name: 2d.path.isPointInPath.bezier + desc: isPointInPath() works on Bezier curves + testing: + - 2d.path.isPointInPath + code: | + ctx.moveTo(25, 25); + ctx.bezierCurveTo(50, -50, 50, 100, 75, 25); + @assert ctx.isPointInPath(25, 20) === false; + @assert ctx.isPointInPath(25, 30) === false; + @assert ctx.isPointInPath(30, 20) === true; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(40, 2) === false; + @assert ctx.isPointInPath(40, 20) === true; + @assert ctx.isPointInPath(40, 30) === false; + @assert ctx.isPointInPath(40, 47) === false; + @assert ctx.isPointInPath(45, 20) === true; + @assert ctx.isPointInPath(45, 30) === false; + @assert ctx.isPointInPath(55, 20) === false; + @assert ctx.isPointInPath(55, 30) === true; + @assert ctx.isPointInPath(60, 2) === false; + @assert ctx.isPointInPath(60, 20) === false; + @assert ctx.isPointInPath(60, 30) === true; + @assert ctx.isPointInPath(60, 47) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(70, 30) === true; + @assert ctx.isPointInPath(75, 20) === false; + @assert ctx.isPointInPath(75, 30) === false; + +- name: 2d.path.isPointInPath.winding + desc: isPointInPath() uses the non-zero winding number rule + testing: + - 2d.path.isPointInPath + code: | + // Create a square ring, using opposite windings to make a hole in the centre + ctx.moveTo(0, 0); + ctx.lineTo(50, 0); + ctx.lineTo(50, 50); + ctx.lineTo(0, 50); + ctx.lineTo(0, 0); + ctx.lineTo(10, 10); + ctx.lineTo(10, 40); + ctx.lineTo(40, 40); + ctx.lineTo(40, 10); + ctx.lineTo(10, 10); + + @assert ctx.isPointInPath(5, 5) === true; + @assert ctx.isPointInPath(25, 5) === true; + @assert ctx.isPointInPath(45, 5) === true; + @assert ctx.isPointInPath(5, 25) === true; + @assert ctx.isPointInPath(25, 25) === false; + @assert ctx.isPointInPath(45, 25) === true; + @assert ctx.isPointInPath(5, 45) === true; + @assert ctx.isPointInPath(25, 45) === true; + @assert ctx.isPointInPath(45, 45) === true; + +- name: 2d.path.isPointInPath.transform.1 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.translate(50, 0); + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.2 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(50, 0, 20, 20); + ctx.translate(50, 0); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.3 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.scale(-1, 1); + ctx.rect(-70, 0, 20, 20); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.4 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.translate(50, 0); + ctx.rect(50, 0, 20, 20); + ctx.translate(0, 50); + @assert ctx.isPointInPath(60, 10) === false; + @assert ctx.isPointInPath(110, 10) === true; + @assert ctx.isPointInPath(110, 60) === false; + +- name: 2d.path.isPointInPath.nonfinite + desc: isPointInPath() returns false for non-finite arguments + testing: + - 2d.path.isPointInPath.nonfinite + code: | + ctx.rect(-100, -50, 200, 100); + @assert ctx.isPointInPath(Infinity, 0) === false; + @assert ctx.isPointInPath(-Infinity, 0) === false; + @assert ctx.isPointInPath(NaN, 0) === false; + @assert ctx.isPointInPath(0, Infinity) === false; + @assert ctx.isPointInPath(0, -Infinity) === false; + @assert ctx.isPointInPath(0, NaN) === false; + @assert ctx.isPointInPath(NaN, NaN) === false; + + +- name: 2d.drawImage.3arg + testing: + - 2d.drawImage.defaultsource + - 2d.drawImage.defaultdest + images: + - red.png + - green.png + code: | + ctx.drawImage(document.getElementById('green.png'), 0, 0); + ctx.drawImage(document.getElementById('red.png'), -100, 0); + ctx.drawImage(document.getElementById('red.png'), 100, 0); + ctx.drawImage(document.getElementById('red.png'), 0, -50); + ctx.drawImage(document.getElementById('red.png'), 0, 50); + + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.5arg + testing: + - 2d.drawImage.defaultsource + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 50, 0, 50, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.9arg.basic + testing: + - 2d.drawImage.paint + images: + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.9arg.sourcepos + testing: + - 2d.drawImage.paint + images: + - rgrg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('rgrg-256x256.png'), 140, 20, 100, 50, 0, 0, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.9arg.sourcesize + testing: + - 2d.drawImage.paint + images: + - rgrg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('rgrg-256x256.png'), 0, 0, 256, 256, 0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 51, 26); + ctx.fillRect(49, 24, 51, 26); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + @assert pixel 20,20 ==~ 0,255,0,255; + @assert pixel 80,20 ==~ 0,255,0,255; + @assert pixel 20,30 ==~ 0,255,0,255; + @assert pixel 80,30 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.9arg.destpos + testing: + - 2d.drawImage.paint + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 0, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -100, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -50, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.9arg.destsize + testing: + - 2d.drawImage.paint + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 1, 1, 1, 1, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, -50, 0, 50, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 100, 0, 50, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, -25, 100, 25); + ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50, 0, 50, 100, 25); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.canvas + testing: + - 2d.drawImage.paint + code: | + var canvas2 = document.createElement('canvas'); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.drawImage(canvas2, 0, 0); + + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.self.1 + testing: + - 2d.drawImage.self + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.drawImage(canvas, 50, 0); + + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.self.2 + testing: + - 2d.drawImage.self + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 1, 100, 49); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 1); + ctx.drawImage(canvas, 0, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 2); + + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.null + testing: + - 2d.drawImage.IDL + code: | + @assert throws TypeError ctx.drawImage(null, 0, 0); + +- name: 2d.drawImage.wrongtype + desc: Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError + notes: *bindings + testing: + - 2d.drawImage.IDL + code: | + @assert throws TypeError ctx.drawImage(undefined, 0, 0); + @assert throws TypeError ctx.drawImage(0, 0, 0); + @assert throws TypeError ctx.drawImage("", 0, 0); + @assert throws TypeError ctx.drawImage(document.createElement('p'), 0, 0); + +- name: 2d.drawImage.floatsource + testing: + - 2d.drawImage.paint + images: + - green.png + code: | + ctx.drawImage(document.getElementById('green.png'), 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.zerosource + desc: drawImage with zero-sized source rectangle draws nothing without exception + testing: + - 2d.drawImage.zerosource + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 1, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 10, 10, 1, 0, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 10, 10, 0, 0, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.zerosource.image + desc: drawImage with zero-sized source rectangle from image throws INDEX_SIZE_ERR + testing: + - 2d.drawImage.zerosource + images: + - red-zerowidth.svg + - red-zeroheight.svg + - red-zerosize.svg + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red-zerowidth.svg'), 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red-zeroheight.svg'), 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red-zerosize.svg'), 0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + expected: green + +- name: 2d.drawImage.negativesource + desc: Negative source width/height represents the correct rectangle + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, -100, 50, 0, 0, 50, 50); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, -100, -50, 50, 0, 50, 50); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.negativedest + desc: Negative destination width/height represents the correct rectangle + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 78, 50, 50, 0, 50, 50, -50); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 100, 128, 50, -50, 100, 50, -50, -50); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.negativedir + desc: Negative dimensions do not affect the direction of the image + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 178, 50, -100, 0, 0, 50, 100); + ctx.drawImage(document.getElementById('ggrr-256x256.png'), 0, 78, 50, 100, 50, 100, 50, -100); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.outsidesource + DISABLED: fix this to match the current spec (transparent black outside source) + testing: + - 2d.drawImage.outsidesource + mozilla: { throws } + images: + - green.png + - red.png + code: | + ctx.drawImage(document.getElementById('green.png'), 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50); + ctx.drawImage(document.getElementById('green.png'), 100, 50, -5, -5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), -0.001, 0, 100, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, -0.001, 100, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100.001, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 100, 50.001, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, -5, 5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 0, 0, 5, -5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(document.getElementById('red.png'), 110, 60, -20, -20, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + expected: green + +- name: 2d.drawImage.incomplete.nosrc + testing: + - 2d.drawImage.incomplete.image + mozilla: { throws } + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.incomplete.immediate + testing: + - 2d.drawImage.incomplete.image + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = new Image(); + img.src = '../images/red.png'; + // This triggers the "update the image data" algorithm. + // The image will not go to the "completely available" state + // until a fetch task in the networking task source is processed, + // so the image must not be fully decodable yet: + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + expected: green + +- name: 2d.drawImage.incomplete.reload + testing: + - 2d.drawImage.incomplete.image + images: + - yellow.png + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('yellow.png'); + img.src = '../images/red.png'; + // This triggers the "update the image data" algorithm, + // and resets the image to the "unavailable" state. + // The image will not go to the "completely available" state + // until a fetch task in the networking task source is processed, + // so the image must not be fully decodable yet: + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + expected: green + +- name: 2d.drawImage.incomplete.emptysrc + testing: + - 2d.drawImage.incomplete.image + images: + - red.png + mozilla: { throws } + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('red.png'); + img.src = ""; + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.incomplete.removedsrc + testing: + - 2d.drawImage.incomplete.image + images: + - red.png + mozilla: { throws } + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('red.png'); + img.removeAttribute('src'); + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.broken + testing: + - 2d.drawImage.incomplete.image + images: + - broken.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var img = document.getElementById('broken.png'); + ctx.drawImage(img, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + expected: green + +- name: 2d.drawImage.zerocanvas + testing: + - 2d.drawImage.zerocanvas + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var canvas2 = document.createElement('canvas'); + canvas2.width = 0; + canvas2.height = 10; + ctx.drawImage(canvas2, 0, 0); + + canvas2.width = 10; + canvas2.height = 0; + ctx.drawImage(canvas2, 0, 0); + + canvas2.width = 0; + canvas2.height = 0; + ctx.drawImage(canvas2, 0, 0); + + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.svg + desc: drawImage() of an SVG image + testing: + - 2d.drawImage.svg + images: + - green.svg + code: | + ctx.drawImage(document.getElementById('green.svg'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.animated.gif + desc: drawImage() of an animated GIF draws the first frame + testing: + - 2d.drawImage.animated.image + images: + - anim-gr.gif + code: | + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.drawImage(document.getElementById('anim-gr.gif'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.drawImage.animated.apng + desc: drawImage() of an APNG with no poster frame draws the first frame + testing: + - 2d.drawImage.animated.image + images: + - anim-gr.png + code: | + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.drawImage(document.getElementById('anim-gr.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.drawImage.animated.poster + desc: drawImage() of an APNG draws the poster frame + testing: + - 2d.drawImage.animated.image + images: + - anim-poster-gr.png + code: | + ctx.drawImage(document.getElementById('anim-poster-gr.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + expected: green + +- name: 2d.drawImage.path + testing: + - 2d.drawImage.unaffect + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('red.png'), 0, 0); + ctx.fill(); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.transform + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 0); + ctx.drawImage(document.getElementById('red.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +# TODO: drawImage shadows + +- name: 2d.drawImage.alpha + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0; + ctx.drawImage(document.getElementById('red.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.clip + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(-10, -10, 1, 1); + ctx.clip(); + ctx.drawImage(document.getElementById('red.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.composite + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; + ctx.drawImage(document.getElementById('red.png'), 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.nowrap + desc: Stretched images do not get pixels wrapping around the edges + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(document.getElementById('redtransparent.png'), -1950, 0, 2000, 50); + @assert pixel 45,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 55,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.drawImage.nonfinite + desc: drawImage() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var red = document.getElementById('red.png'); + @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @nonfinite ctx.drawImage(<red>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @assert pixel 50,25 == 0,255,0,255; + expected: green + + + +- name: 2d.imageData.create2.basic + desc: createImageData(sw, sh) exists and returns something + testing: + - 2d.imageData.create2.object + code: | + @assert ctx.createImageData(1, 1) !== null; + +- name: 2d.imageData.create1.basic + desc: createImageData(imgdata) exists and returns something + testing: + - 2d.imageData.create1.object + code: | + @assert ctx.createImageData(ctx.createImageData(1, 1)) !== null; + +- name: 2d.imageData.create2.type + desc: createImageData(sw, sh) returns an ImageData object containing a Uint8ClampedArray object + testing: + - 2d.imageData.create2.object + code: | + @assert window.ImageData !== undefined; + @assert window.Uint8ClampedArray !== undefined; + window.ImageData.prototype.thisImplementsImageData = true; + window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; + var imgdata = ctx.createImageData(1, 1); + @assert imgdata.thisImplementsImageData; + @assert imgdata.data.thisImplementsUint8ClampedArray; + +- name: 2d.imageData.create1.type + desc: createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object + testing: + - 2d.imageData.create1.object + code: | + @assert window.ImageData !== undefined; + @assert window.Uint8ClampedArray !== undefined; + window.ImageData.prototype.thisImplementsImageData = true; + window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; + var imgdata = ctx.createImageData(ctx.createImageData(1, 1)); + @assert imgdata.thisImplementsImageData; + @assert imgdata.data.thisImplementsUint8ClampedArray; + +- name: 2d.imageData.create2.this + desc: createImageData(sw, sh) should throw when called with the wrong |this| + notes: *bindings + testing: + - 2d.imageData.create2.object + code: | + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(null, 1, 1); @moz-todo + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(undefined, 1, 1); @moz-todo + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call({}, 1, 1); @moz-todo + +- name: 2d.imageData.create1.this + desc: createImageData(imgdata) should throw when called with the wrong |this| + notes: *bindings + testing: + - 2d.imageData.create2.object + code: | + var imgdata = ctx.createImageData(1, 1); + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(null, imgdata); @moz-todo + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call(undefined, imgdata); @moz-todo + @assert throws TypeError CanvasRenderingContext2D.prototype.createImageData.call({}, imgdata); @moz-todo + +- name: 2d.imageData.create2.initial + desc: createImageData(sw, sh) returns transparent black data of the right size + testing: + - 2d.imageData.create2.size + - 2d.imageData.create.initial + - 2d.imageData.initial + code: | + var imgdata = ctx.createImageData(10, 20); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + @assert imgdata.width < imgdata.height; + @assert imgdata.width > 0; + var isTransparentBlack = true; + for (var i = 0; i < imgdata.data.length; ++i) + if (imgdata.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create1.initial + desc: createImageData(imgdata) returns transparent black data of the right size + testing: + - 2d.imageData.create1.size + - 2d.imageData.create.initial + - 2d.imageData.initial + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var imgdata1 = ctx.getImageData(0, 0, 10, 20); + var imgdata2 = ctx.createImageData(imgdata1); + @assert imgdata2.data.length === imgdata1.data.length; + @assert imgdata2.width === imgdata1.width; + @assert imgdata2.height === imgdata1.height; + var isTransparentBlack = true; + for (var i = 0; i < imgdata2.data.length; ++i) + if (imgdata2.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create2.large + desc: createImageData(sw, sh) works for sizes much larger than the canvas + testing: + - 2d.imageData.create2.size + code: | + var imgdata = ctx.createImageData(1000, 2000); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + @assert imgdata.width < imgdata.height; + @assert imgdata.width > 0; + var isTransparentBlack = true; + for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling) + if (imgdata.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create2.negative + desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments + testing: + - 2d.imageData.create2.size + code: | + var imgdata1 = ctx.createImageData(10, 20); + var imgdata2 = ctx.createImageData(-10, 20); + var imgdata3 = ctx.createImageData(10, -20); + var imgdata4 = ctx.createImageData(-10, -20); + @assert imgdata1.data.length === imgdata2.data.length; + @assert imgdata2.data.length === imgdata3.data.length; + @assert imgdata3.data.length === imgdata4.data.length; + +- name: 2d.imageData.create2.zero + desc: createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero + testing: + - 2d.imageData.getcreate.zero + code: | + @assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0); + @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 10); + @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 0); + @assert throws INDEX_SIZE_ERR ctx.createImageData(0.99, 10); + @assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0.1); + +- name: 2d.imageData.create2.nonfinite + desc: createImageData() throws TypeError if arguments are not finite + notes: *bindings + testing: + - 2d.imageData.getcreate.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + var posinfobj = { valueOf: function() { return Infinity; } }, + neginfobj = { valueOf: function() { return -Infinity; } }, + nanobj = { valueOf: function() { return -Infinity; } }; + @nonfinite @assert throws TypeError ctx.createImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>); + +- name: 2d.imageData.create1.zero + desc: createImageData(null) throws TypeError + testing: + - 2d.imageData.create.null + code: | + @assert throws TypeError ctx.createImageData(null); + +- name: 2d.imageData.create2.double + desc: createImageData(w, h) double is converted to long + testing: + - 2d.imageData.create2.size + code: | + var imgdata1 = ctx.createImageData(10.01, 10.99); + var imgdata2 = ctx.createImageData(-10.01, -10.99); + @assert imgdata1.width === 10; + @assert imgdata1.height === 10; + @assert imgdata2.width === 10; + @assert imgdata2.height === 10; + +- name: 2d.imageData.get.basic + desc: getImageData() exists and returns something + testing: + - 2d.imageData.get.basic + code: | + @assert ctx.getImageData(0, 0, 100, 50) !== null; + +- name: 2d.imageData.get.type + desc: getImageData() returns an ImageData object containing a Uint8ClampedArray object + testing: + - 2d.imageData.get.object + code: | + @assert window.ImageData !== undefined; + @assert window.Uint8ClampedArray !== undefined; + window.ImageData.prototype.thisImplementsImageData = true; + window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true; + var imgdata = ctx.getImageData(0, 0, 1, 1); + @assert imgdata.thisImplementsImageData; + @assert imgdata.data.thisImplementsUint8ClampedArray; + +- name: 2d.imageData.get.zero + desc: getImageData() throws INDEX_SIZE_ERR if size is zero + testing: + - 2d.imageData.getcreate.zero + code: | + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 10); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 0); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0.1, 10); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0.99); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, -0.1, 10); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, -0.99); + +- name: 2d.imageData.get.nonfinite + desc: getImageData() throws TypeError if arguments are not finite + notes: *bindings + testing: + - 2d.imageData.getcreate.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.getImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + var posinfobj = { valueOf: function() { return Infinity; } }, + neginfobj = { valueOf: function() { return -Infinity; } }, + nanobj = { valueOf: function() { return -Infinity; } }; + @nonfinite @assert throws TypeError ctx.getImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>); + +- name: 2d.imageData.get.source.outside + desc: getImageData() returns transparent black outside the canvas + testing: + - 2d.imageData.get.basic + - 2d.imageData.get.outside + code: | + ctx.fillStyle = '#08f'; + ctx.fillRect(0, 0, 100, 50); + + var imgdata1 = ctx.getImageData(-10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + @assert imgdata1.data[1] === 0; + @assert imgdata1.data[2] === 0; + @assert imgdata1.data[3] === 0; + + var imgdata2 = ctx.getImageData(10, -5, 1, 1); + @assert imgdata2.data[0] === 0; + @assert imgdata2.data[1] === 0; + @assert imgdata2.data[2] === 0; + @assert imgdata2.data[3] === 0; + + var imgdata3 = ctx.getImageData(200, 5, 1, 1); + @assert imgdata3.data[0] === 0; + @assert imgdata3.data[1] === 0; + @assert imgdata3.data[2] === 0; + @assert imgdata3.data[3] === 0; + + var imgdata4 = ctx.getImageData(10, 60, 1, 1); + @assert imgdata4.data[0] === 0; + @assert imgdata4.data[1] === 0; + @assert imgdata4.data[2] === 0; + @assert imgdata4.data[3] === 0; + + var imgdata5 = ctx.getImageData(100, 10, 1, 1); + @assert imgdata5.data[0] === 0; + @assert imgdata5.data[1] === 0; + @assert imgdata5.data[2] === 0; + @assert imgdata5.data[3] === 0; + + var imgdata6 = ctx.getImageData(0, 10, 1, 1); + @assert imgdata6.data[0] === 0; + @assert imgdata6.data[1] === 136; + @assert imgdata6.data[2] === 255; + @assert imgdata6.data[3] === 255; + + var imgdata7 = ctx.getImageData(-10, 10, 20, 20); + @assert imgdata7.data[ 0*4+0] === 0; + @assert imgdata7.data[ 0*4+1] === 0; + @assert imgdata7.data[ 0*4+2] === 0; + @assert imgdata7.data[ 0*4+3] === 0; + @assert imgdata7.data[ 9*4+0] === 0; + @assert imgdata7.data[ 9*4+1] === 0; + @assert imgdata7.data[ 9*4+2] === 0; + @assert imgdata7.data[ 9*4+3] === 0; + @assert imgdata7.data[10*4+0] === 0; + @assert imgdata7.data[10*4+1] === 136; + @assert imgdata7.data[10*4+2] === 255; + @assert imgdata7.data[10*4+3] === 255; + @assert imgdata7.data[19*4+0] === 0; + @assert imgdata7.data[19*4+1] === 136; + @assert imgdata7.data[19*4+2] === 255; + @assert imgdata7.data[19*4+3] === 255; + @assert imgdata7.data[20*4+0] === 0; + @assert imgdata7.data[20*4+1] === 0; + @assert imgdata7.data[20*4+2] === 0; + @assert imgdata7.data[20*4+3] === 0; + +- name: 2d.imageData.get.source.negative + desc: getImageData() works with negative width and height, and returns top-to-bottom left-to-right + testing: + - 2d.imageData.get.basic + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#fff'; + ctx.fillRect(20, 10, 60, 10); + + var imgdata1 = ctx.getImageData(85, 25, -10, -10); + @assert imgdata1.data[0] === 255; + @assert imgdata1.data[1] === 255; + @assert imgdata1.data[2] === 255; + @assert imgdata1.data[3] === 255; + @assert imgdata1.data[imgdata1.data.length-4+0] === 0; + @assert imgdata1.data[imgdata1.data.length-4+1] === 0; + @assert imgdata1.data[imgdata1.data.length-4+2] === 0; + @assert imgdata1.data[imgdata1.data.length-4+3] === 255; + + var imgdata2 = ctx.getImageData(0, 0, -1, -1); + @assert imgdata2.data[0] === 0; + @assert imgdata2.data[1] === 0; + @assert imgdata2.data[2] === 0; + @assert imgdata2.data[3] === 0; + +- name: 2d.imageData.get.source.size + desc: getImageData() returns bigger ImageData for bigger source rectangle + testing: + - 2d.imageData.get.basic + code: | + var imgdata1 = ctx.getImageData(0, 0, 10, 10); + var imgdata2 = ctx.getImageData(0, 0, 20, 20); + @assert imgdata2.width > imgdata1.width; + @assert imgdata2.height > imgdata1.height; + +- name: 2d.imageData.get.double + desc: createImageData(w, h) double is converted to long + testing: + - 2d.imageData.get.basic + code: | + var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99); + var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99); + @assert imgdata1.width === 10; + @assert imgdata1.height === 10; + @assert imgdata2.width === 10; + @assert imgdata2.height === 10; + +- name: 2d.imageData.get.nonpremul + desc: getImageData() returns non-premultiplied colours + testing: + - 2d.imageData.get.premul + code: | + ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(10, 10, 10, 10); + @assert imgdata.data[0] > 200; + @assert imgdata.data[1] > 200; + @assert imgdata.data[2] > 200; + @assert imgdata.data[3] > 100; + @assert imgdata.data[3] < 200; + +- name: 2d.imageData.get.range + desc: getImageData() returns values in the range [0, 255] + testing: + - 2d.pixelarray.range + - 2d.pixelarray.retrieve + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#fff'; + ctx.fillRect(20, 10, 60, 10); + var imgdata1 = ctx.getImageData(10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + var imgdata2 = ctx.getImageData(30, 15, 1, 1); + @assert imgdata2.data[0] === 255; + +- name: 2d.imageData.get.clamp + desc: getImageData() clamps colours to the range [0, 255] + testing: + - 2d.pixelarray.range + code: | + ctx.fillStyle = 'rgb(-100, -200, -300)'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = 'rgb(256, 300, 400)'; + ctx.fillRect(20, 10, 60, 10); + var imgdata1 = ctx.getImageData(10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + @assert imgdata1.data[1] === 0; + @assert imgdata1.data[2] === 0; + var imgdata2 = ctx.getImageData(30, 15, 1, 1); + @assert imgdata2.data[0] === 255; + @assert imgdata2.data[1] === 255; + @assert imgdata2.data[2] === 255; + +- name: 2d.imageData.get.length + desc: getImageData() returns a correctly-sized Uint8ClampedArray + testing: + - 2d.pixelarray.length + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + +- name: 2d.imageData.get.order.cols + desc: getImageData() returns leftmost columns first + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 2, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0; + @assert imgdata.data[Math.round(imgdata.width/2*4)] === 255; + @assert imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)] === 0; + +- name: 2d.imageData.get.order.rows + desc: getImageData() returns topmost rows first + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 2); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0; + @assert imgdata.data[Math.floor(imgdata.width/2*4)] === 0; + @assert imgdata.data[(imgdata.height/2)*imgdata.width*4] === 255; + +- name: 2d.imageData.get.order.rgb + desc: getImageData() returns R then G then B + testing: + - 2d.pixelarray.order + - 2d.pixelarray.indexes + code: | + ctx.fillStyle = '#48c'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0x44; + @assert imgdata.data[1] === 0x88; + @assert imgdata.data[2] === 0xCC; + @assert imgdata.data[3] === 255; + @assert imgdata.data[4] === 0x44; + @assert imgdata.data[5] === 0x88; + @assert imgdata.data[6] === 0xCC; + @assert imgdata.data[7] === 255; + +- name: 2d.imageData.get.order.alpha + desc: getImageData() returns A in the fourth component + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[3] < 200; + @assert imgdata.data[3] > 100; + +- name: 2d.imageData.get.unaffected + desc: getImageData() is not affected by context state + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50) + ctx.save(); + ctx.translate(50, 0); + ctx.globalAlpha = 0.1; + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.rect(0, 0, 5, 5); + ctx.clip(); + var imgdata = ctx.getImageData(0, 0, 50, 50); + ctx.restore(); + ctx.putImageData(imgdata, 50, 0); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + + +- name: 2d.imageData.object.properties + desc: ImageData objects have the right properties + testing: + - 2d.imageData.type + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert typeof(imgdata.width) === 'number'; + @assert typeof(imgdata.height) === 'number'; + @assert typeof(imgdata.data) === 'object'; + +- name: 2d.imageData.object.readonly + desc: ImageData objects properties are read-only + testing: + - 2d.imageData.type + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + var w = imgdata.width; + var h = imgdata.height; + var d = imgdata.data; + imgdata.width = 123; + imgdata.height = 123; + imgdata.data = [100,100,100,100]; + @assert imgdata.width === w; + @assert imgdata.height === h; + @assert imgdata.data === d; + @assert imgdata.data[0] === 0; + @assert imgdata.data[1] === 0; + @assert imgdata.data[2] === 0; + @assert imgdata.data[3] === 0; + +- name: 2d.imageData.object.ctor.size + desc: ImageData has a usable constructor + testing: + - 2d.imageData.type + code: | + @assert window.ImageData !== undefined; + + var imgdata = new window.ImageData(2, 3); + @assert imgdata.width === 2; + @assert imgdata.height === 3; + @assert imgdata.data.length === 2 * 3 * 4; + for (var i = 0; i < imgdata.data.length; ++i) { + @assert imgdata.data[i] === 0; + } + +- name: 2d.imageData.object.ctor.size.bounds + desc: ImageData has a usable constructor + testing: + - 2d.imageData.type + code: | + @assert window.ImageData !== undefined; + @assert throws INDEX_SIZE_ERR new window.ImageData(0, 0); + @assert throws INDEX_SIZE_ERR new window.ImageData(0, 1); + @assert throws INDEX_SIZE_ERR new window.ImageData(1, 0); + +- name: 2d.imageData.object.ctor.array + desc: ImageData has a usable constructor + testing: + - 2d.imageData.type + code: | + @assert window.ImageData !== undefined; + + var array = new Uint8ClampedArray(8); + var imgdata = new window.ImageData(array, 1, 2); + @assert imgdata.width === 1; + @assert imgdata.height === 2; + @assert imgdata.data === array; + +- name: 2d.imageData.object.ctor.array.bounds + desc: ImageData has a usable constructor + testing: + - 2d.imageData.type + code: | + @assert window.ImageData !== undefined; + + @assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(0), 1); + @assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(3), 1); + @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 0); + @assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 1, 2); + @assert throws TypeError new ImageData(new Uint8Array(8), 1, 2); + @assert throws TypeError new ImageData(new Int8Array(8), 1, 2); + +- name: 2d.imageData.object.set + desc: ImageData.data can be modified + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + @assert imgdata.data[0] === 100; + imgdata.data[0] = 200; + @assert imgdata.data[0] === 200; + +- name: 2d.imageData.object.undefined + desc: ImageData.data converts undefined to 0 + testing: + - 2d.pixelarray.modify + webidl: + - es-octet + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = undefined; + @assert imgdata.data[0] === 0; + +- name: 2d.imageData.object.nan + desc: ImageData.data converts NaN to 0 + testing: + - 2d.pixelarray.modify + webidl: + - es-octet + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = NaN; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = "cheese"; + @assert imgdata.data[0] === 0; + +- name: 2d.imageData.object.string + desc: ImageData.data converts strings to numbers with ToNumber + testing: + - 2d.pixelarray.modify + webidl: + - es-octet + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = "110"; + @assert imgdata.data[0] === 110; + imgdata.data[0] = 100; + imgdata.data[0] = "0x78"; + @assert imgdata.data[0] === 120; + imgdata.data[0] = 100; + imgdata.data[0] = " +130e0 "; + @assert imgdata.data[0] === 130; + +- name: 2d.imageData.object.clamp + desc: ImageData.data clamps numbers to [0, 255] + testing: + - 2d.pixelarray.modify + webidl: + - es-octet + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + + imgdata.data[0] = 100; + imgdata.data[0] = 300; + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -100; + @assert imgdata.data[0] === 0; + + imgdata.data[0] = 100; + imgdata.data[0] = 200+Math.pow(2, 32); + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -200-Math.pow(2, 32); + @assert imgdata.data[0] === 0; + + imgdata.data[0] = 100; + imgdata.data[0] = Math.pow(10, 39); + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -Math.pow(10, 39); + @assert imgdata.data[0] === 0; + + imgdata.data[0] = 100; + imgdata.data[0] = -Infinity; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = Infinity; + @assert imgdata.data[0] === 255; + +- name: 2d.imageData.object.round + desc: ImageData.data rounds numbers with round-to-zero + testing: + - 2d.pixelarray.modify + webidl: + - es-octet + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 0.499; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 0.5; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 0.501; + @assert imgdata.data[0] === 1; + imgdata.data[0] = 1.499; + @assert imgdata.data[0] === 1; + imgdata.data[0] = 1.5; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 1.501; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 2.5; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 3.5; + @assert imgdata.data[0] === 4; + imgdata.data[0] = 252.5; + @assert imgdata.data[0] === 252; + imgdata.data[0] = 253.5; + @assert imgdata.data[0] === 254; + imgdata.data[0] = 254.5; + @assert imgdata.data[0] === 254; + imgdata.data[0] = 256.5; + @assert imgdata.data[0] === 255; + imgdata.data[0] = -0.5; + @assert imgdata.data[0] === 0; + imgdata.data[0] = -1.5; + @assert imgdata.data[0] === 0; + + + +- name: 2d.imageData.put.null + desc: putImageData() with null imagedata throws TypeError + testing: + - 2d.imageData.put.wrongtype + code: | + @assert throws TypeError ctx.putImageData(null, 0, 0); + +- name: 2d.imageData.put.nonfinite + desc: putImageData() throws TypeError if arguments are not finite + notes: *bindings + testing: + - 2d.imageData.put.nonfinite + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + +- name: 2d.imageData.put.basic + desc: putImageData() puts image data from getImageData() onto the canvas + testing: + - 2d.imageData.put.normal + - 2d.imageData.put.3arg + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.created + desc: putImageData() puts image data from createImageData() onto the canvas + testing: + - 2d.imageData.put.normal + code: | + var imgdata = ctx.createImageData(100, 50); + for (var i = 0; i < imgdata.data.length; i += 4) { + imgdata.data[i] = 0; + imgdata.data[i+1] = 255; + imgdata.data[i+2] = 0; + imgdata.data[i+3] = 255; + } + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.wrongtype + desc: putImageData() does not accept non-ImageData objects + testing: + - 2d.imageData.put.wrongtype + code: | + var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] }; + @assert throws TypeError ctx.putImageData(imgdata, 0, 0); + @assert throws TypeError ctx.putImageData("cheese", 0, 0); + @assert throws TypeError ctx.putImageData(42, 0, 0); + expected: green + +- name: 2d.imageData.put.cross + desc: putImageData() accepts image data got from a different canvas + testing: + - 2d.imageData.put.normal + code: | + var canvas2 = document.createElement('canvas'); + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50) + var imgdata = ctx2.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.alpha + desc: putImageData() puts non-solid image data correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = 'rgba(0, 255, 0, 0.25)'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,64; + expected: | + size 100 50 + cr.set_source_rgba(0, 1, 0, 0.25) + cr.rectangle(0, 0, 100, 50) + cr.fill() + +- name: 2d.imageData.put.modified + desc: putImageData() puts modified image data correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(45, 20, 10, 10) + var imgdata = ctx.getImageData(45, 20, 10, 10); + for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4) + { + imgdata.data[i] = 0; + imgdata.data[i+1] = 255; + } + ctx.putImageData(imgdata, 45, 20); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.dirty.zero + desc: putImageData() with zero-sized dirty rectangle puts nothing + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.dirty.rect1 + desc: putImageData() only modifies areas inside the dirty rectangle, using width and height + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 20, 20) + + var imgdata = ctx.getImageData(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20); + + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.dirty.rect2 + desc: putImageData() only modifies areas inside the dirty rectangle, using x and y + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(60, 30, 20, 20) + + var imgdata = ctx.getImageData(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20); + + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.dirty.negative + desc: putImageData() handles negative-sized dirty rectangles correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 20, 20) + + var imgdata = ctx.getImageData(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20); + + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.dirty.outside + desc: putImageData() handles dirty rectangles outside the canvas correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + + var imgdata = ctx.getImageData(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + + ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20); + ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50); + ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20); + ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20); + + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 98,15 ==~ 0,255,0,255; + @assert pixel 98,25 ==~ 0,255,0,255; + @assert pixel 98,45 ==~ 0,255,0,255; + @assert pixel 1,5 ==~ 0,255,0,255; + @assert pixel 1,25 ==~ 0,255,0,255; + @assert pixel 1,45 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.unchanged + desc: putImageData(getImageData(...), ...) has no effect + testing: + - 2d.imageData.unchanged + code: | + var i = 0; + for (var y = 0; y < 16; ++y) { + for (var x = 0; x < 16; ++x, ++i) { + ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')'; + ctx.fillRect(x, y, 1, 1); + } + } + var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9); + var olddata = []; + for (var i = 0; i < imgdata1.data.length; ++i) + olddata[i] = imgdata1.data[i]; + + ctx.putImageData(imgdata1, 0.1, 0.2); + + var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9); + for (var i = 0; i < imgdata2.data.length; ++i) { + @assert olddata[i] === imgdata2.data[i]; + } + +- name: 2d.imageData.put.unaffected + desc: putImageData() is not affected by context state + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.globalAlpha = 0.1; + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 1; + ctx.translate(100, 50); + ctx.scale(0.1, 0.1); + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.clip + desc: putImageData() is not affected by clipping regions + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.putImageData(imgdata, 0, 0); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + expected: green + +- name: 2d.imageData.put.path + desc: putImageData() does not affect the current path + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.rect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.putImageData(imgdata, 0, 0); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 ==~ 0,255,0,255; + expected: green
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2dtext.yaml b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2dtext.yaml new file mode 100644 index 0000000..9b168e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/tools/tests2dtext.yaml
@@ -0,0 +1,1013 @@ +# Copyright (c) 2010 Philip Taylor +# Released under the BSD license and W3C Test Suite License: see LICENSE.txt + +- name: 2d.text.font.parse.basic + testing: + - 2d.text.font.parse + - 2d.text.font.get + code: | + ctx.font = '20px serif'; + @assert ctx.font === '20px serif'; + + ctx.font = '20PX SERIF'; + @assert ctx.font === '20px serif'; @moz-todo + +- name: 2d.text.font.parse.complex + testing: + - 2d.text.font.parse + - 2d.text.font.get + - 2d.text.font.lineheight + code: | + ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif'; + @assert ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif'; @moz-todo + + # TODO: + # 2d.text.font.parse.size.absolute + # xx-small x-small small medium large x-large xx-large + # 2d.text.font.parse.size.relative + # smaller larger + # 2d.text.font.parse.size.length.relative + # em ex px + # 2d.text.font.parse.size.length.absolute + # in cm mm pt pc + +- name: 2d.text.font.parse.size.percentage + testing: + - 2d.text.font.parse + - 2d.text.font.get + - 2d.text.font.fontsize + - 2d.text.font.size + canvas: 'style="font-size: 144px" width="100" height="50"' + code: | + ctx.font = '50% serif'; + @assert ctx.font === '72px serif'; @moz-todo + canvas.setAttribute('style', 'font-size: 100px'); + @assert ctx.font === '72px serif'; @moz-todo + +- name: 2d.text.font.parse.size.percentage.default + testing: + - 2d.text.font.undefined + code: | + var canvas2 = document.createElement('canvas'); + var ctx2 = canvas2.getContext('2d'); + ctx2.font = '1000% serif'; + @assert ctx2.font === '100px serif'; @moz-todo + +- name: 2d.text.font.parse.system + desc: System fonts must be computed to explicit values + testing: + - 2d.text.font.parse + - 2d.text.font.get + - 2d.text.font.systemfonts + code: | + ctx.font = 'message-box'; + @assert ctx.font !== 'message-box'; + +- name: 2d.text.font.parse.invalid + testing: + - 2d.text.font.invalid + code: | + ctx.font = '20px serif'; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; + ctx.font = 'bogus'; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; + ctx.font = 'inherit'; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; + ctx.font = '10px {bogus}'; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; + ctx.font = '10px initial'; + @assert ctx.font === '20px serif'; @moz-todo + + ctx.font = '20px serif'; + ctx.font = '10px default'; + @assert ctx.font === '20px serif'; @moz-todo + + ctx.font = '20px serif'; + ctx.font = '10px inherit'; + @assert ctx.font === '20px serif'; + + ctx.font = '20px serif'; + ctx.font = '1em serif; background: green; margin: 10px'; + @assert ctx.font === '20px serif'; + +- name: 2d.text.font.default + testing: + - 2d.text.font.default + code: | + @assert ctx.font === '10px sans-serif'; + + + +- name: 2d.text.align.valid + testing: + - 2d.text.align.get + - 2d.text.align.set + code: | + ctx.textAlign = 'start'; + @assert ctx.textAlign === 'start'; + + ctx.textAlign = 'end'; + @assert ctx.textAlign === 'end'; + + ctx.textAlign = 'left'; + @assert ctx.textAlign === 'left'; + + ctx.textAlign = 'right'; + @assert ctx.textAlign === 'right'; + + ctx.textAlign = 'center'; + @assert ctx.textAlign === 'center'; + +- name: 2d.text.align.invalid + testing: + - 2d.text.align.invalid + code: | + ctx.textAlign = 'start'; + ctx.textAlign = 'bogus'; + @assert ctx.textAlign === 'start'; + + ctx.textAlign = 'start'; + ctx.textAlign = 'END'; + @assert ctx.textAlign === 'start'; + + ctx.textAlign = 'start'; + ctx.textAlign = 'end '; + @assert ctx.textAlign === 'start'; + + ctx.textAlign = 'start'; + ctx.textAlign = 'end\0'; + @assert ctx.textAlign === 'start'; + +- name: 2d.text.align.default + testing: + - 2d.text.align.default + code: | + @assert ctx.textAlign === 'start'; + + +- name: 2d.text.baseline.valid + testing: + - 2d.text.baseline.get + - 2d.text.baseline.set + code: | + ctx.textBaseline = 'top'; + @assert ctx.textBaseline === 'top'; + + ctx.textBaseline = 'hanging'; + @assert ctx.textBaseline === 'hanging'; + + ctx.textBaseline = 'middle'; + @assert ctx.textBaseline === 'middle'; + + ctx.textBaseline = 'alphabetic'; + @assert ctx.textBaseline === 'alphabetic'; + + ctx.textBaseline = 'ideographic'; + @assert ctx.textBaseline === 'ideographic'; + + ctx.textBaseline = 'bottom'; + @assert ctx.textBaseline === 'bottom'; + +- name: 2d.text.baseline.invalid + testing: + - 2d.text.baseline.invalid + code: | + ctx.textBaseline = 'top'; + ctx.textBaseline = 'bogus'; + @assert ctx.textBaseline === 'top'; + + ctx.textBaseline = 'top'; + ctx.textBaseline = 'MIDDLE'; + @assert ctx.textBaseline === 'top'; + + ctx.textBaseline = 'top'; + ctx.textBaseline = 'middle '; + @assert ctx.textBaseline === 'top'; + + ctx.textBaseline = 'top'; + ctx.textBaseline = 'middle\0'; + @assert ctx.textBaseline === 'top'; + +- name: 2d.text.baseline.default + testing: + - 2d.text.baseline.default + code: | + @assert ctx.textBaseline === 'alphabetic'; + + + + + +- name: 2d.text.draw.fill.basic + desc: fillText draws filled text + manual: + testing: + - 2d.text.draw + - 2d.text.draw.fill + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('PASS', 5, 35); + expected: &passfill | + size 100 50 + cr.set_source_rgb(0, 0, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 0) + cr.select_font_face("Arial") + cr.set_font_size(35) + cr.translate(5, 35) + cr.text_path("PASS") + cr.fill() + +- name: 2d.text.draw.fill.unaffected + desc: fillText does not start a new path or subpath + testing: + - 2d.text.draw.fill + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('FAIL', 5, 35); + + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; + expected: green + +- name: 2d.text.draw.fill.rtl + desc: fillText respects Right-To-Left Override characters + manual: + testing: + - 2d.text.draw + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('\u202eFAIL \xa0 \xa0 SSAP', 5, 35); + expected: *passfill + +- name: 2d.text.draw.fill.maxWidth.large + desc: fillText handles maxWidth correctly + manual: + testing: + - 2d.text.draw.maxwidth + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('PASS', 5, 35, 200); + expected: *passfill + +- name: 2d.text.draw.fill.maxWidth.small + desc: fillText handles maxWidth correctly + testing: + - 2d.text.draw.maxwidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('fail fail fail fail fail', -100, 35, 90); + _assertGreen(ctx, 100, 50); + expected: green + +- name: 2d.text.draw.fill.maxWidth.zero + desc: fillText handles maxWidth correctly + testing: + - 2d.text.draw.maxwidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('fail fail fail fail fail', 5, 35, 0); + _assertGreen(ctx, 100, 50); + expected: green + +- name: 2d.text.draw.fill.maxWidth.negative + desc: fillText handles maxWidth correctly + testing: + - 2d.text.draw.maxwidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('fail fail fail fail fail', 5, 35, -1); + _assertGreen(ctx, 100, 50); + expected: green + +- name: 2d.text.draw.fill.maxWidth.NaN + desc: fillText handles maxWidth correctly + testing: + - 2d.text.draw.maxwidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.font = '35px Arial, sans-serif'; + ctx.fillText('fail fail fail fail fail', 5, 35, NaN); + _assertGreen(ctx, 100, 50); + expected: green + +- name: 2d.text.draw.stroke.basic + desc: strokeText draws stroked text + manual: + testing: + - 2d.text.draw + - 2d.text.draw.stroke + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.fillStyle = '#f00'; + ctx.lineWidth = 1; + ctx.font = '35px Arial, sans-serif'; + ctx.strokeText('PASS', 5, 35); + expected: | + size 100 50 + cr.set_source_rgb(0, 0, 0) + cr.rectangle(0, 0, 100, 50) + cr.fill() + cr.set_source_rgb(0, 1, 0) + cr.select_font_face("Arial") + cr.set_font_size(35) + cr.set_line_width(1) + cr.translate(5, 35) + cr.text_path("PASS") + cr.stroke() + +- name: 2d.text.draw.stroke.unaffected + desc: strokeText does not start a new path or subpath + testing: + - 2d.text.draw.stroke + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + + ctx.font = '35px Arial, sans-serif'; + ctx.strokeStyle = '#f00'; + ctx.strokeText('FAIL', 5, 35); + + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; + expected: green + +- name: 2d.text.draw.kern.consistent + desc: Stroked and filled text should have exactly the same kerning so it overlaps + manual: + testing: + - 2d.text.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 3; + ctx.font = '20px Arial, sans-serif'; + ctx.fillText('VAVAVAVAVAVAVA', -50, 25); + ctx.fillText('ToToToToToToTo', -50, 45); + ctx.strokeText('VAVAVAVAVAVAVA', -50, 25); + ctx.strokeText('ToToToToToToTo', -50, 45); + expected: green + +# CanvasTest is: +# A = (0, 0) to (1em, 0.75em) (above baseline) +# B = (0, 0) to (1em, -0.25em) (below baseline) +# C = (0, -0.25em) to (1em, 0.75em) (the em square) plus some Xs above and below +# D = (0, -0.25em) to (1em, 0.75em) (the em square) plus some Xs left and right +# E = (0, -0.25em) to (1em, 0.75em) (the em square) +# space = empty, 1em wide +# +# At 50px, "E" will fill the canvas vertically +# At 67px, "A" will fill the canvas vertically +# +# Ideographic baseline is 0.125em above alphabetic +# Mathematical baseline is 0.375em above alphabetic +# Hanging baseline is 0.500em above alphabetic + +# WebKit doesn't block onload on font loads, so we try to make it a bit more reliable +# by waiting with step_timeout after load before drawing + +- name: 2d.text.draw.fill.maxWidth.fontface + desc: fillText works on @font-face fonts + testing: + - 2d.text.draw.maxwidth + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillText('EEEE', -50, 37.5, 40); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.fill.maxWidth.bound + desc: fillText handles maxWidth based on line size, not bounding box size + testing: + - 2d.text.draw.maxwidth + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('DD', 0, 37.5, 100); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.fontface + testing: + - 2d.text.font.fontface + fonts: + - CanvasTest + code: | + ctx.font = '67px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('AA', 0, 50); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.fontface.repeat + desc: Draw with the font immediately, then wait a bit until and draw again. (This crashes some version of WebKit.) + testing: + - 2d.text.font.fontface + fonts: + - CanvasTest + fonthack: 0 + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.font = '67px CanvasTest'; + ctx.fillStyle = '#0f0'; + ctx.fillText('AA', 0, 50); + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillText('AA', 0, 50); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.fontface.notinpage + desc: "@font-face fonts should work even if they are not used in the page" + testing: + - 2d.text.font.fontface + fonts: + - CanvasTest + fonthack: 0 + code: | + ctx.font = '67px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('AA', 0, 50); + @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo + @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo + @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo + @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo + }), 500); + expected: green + +- name: 2d.text.draw.baseline.top + desc: textBaseline top is the top of the em square (not the bounding box) + testing: + - 2d.text.baseline.top + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'top'; + ctx.fillText('CC', 0, 0); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.baseline.bottom + desc: textBaseline bottom is the bottom of the em square (not the bounding box) + testing: + - 2d.text.baseline.bottom + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'bottom'; + ctx.fillText('CC', 0, 50); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.baseline.middle + desc: textBaseline middle is the middle of the em square (not the bounding box) + testing: + - 2d.text.baseline.middle + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'middle'; + ctx.fillText('CC', 0, 25); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.baseline.alphabetic + testing: + - 2d.text.baseline.alphabetic + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'alphabetic'; + ctx.fillText('CC', 0, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.baseline.ideographic + testing: + - 2d.text.baseline.ideographic + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'ideographic'; + ctx.fillText('CC', 0, 31.25); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; @moz-todo + @assert pixel 95,45 ==~ 0,255,0,255; @moz-todo + }), 500); + expected: green + +- name: 2d.text.draw.baseline.hanging + testing: + - 2d.text.baseline.hanging + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textBaseline = 'hanging'; + ctx.fillText('CC', 0, 12.5); + @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo + @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.left + desc: textAlign left is the left of the first em square (not the bounding box) + testing: + - 2d.text.align.left + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'left'; + ctx.fillText('DD', 0, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.right + desc: textAlign right is the right of the last em square (not the bounding box) + testing: + - 2d.text.align.right + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'right'; + ctx.fillText('DD', 100, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.start.ltr + desc: textAlign start with ltr is the left edge + testing: + - 2d.text.align.left + fonts: + - CanvasTest + canvas: width="100" height="50" dir="ltr" + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'start'; + ctx.fillText('DD', 0, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.start.rtl + desc: textAlign start with rtl is the right edge + testing: + - 2d.text.align.right + - 2d.text.draw.direction + fonts: + - CanvasTest + canvas: width="100" height="50" dir="rtl" + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'start'; + ctx.fillText('DD', 100, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.end.ltr + desc: textAlign end with ltr is the right edge + testing: + - 2d.text.align.right + fonts: + - CanvasTest + canvas: width="100" height="50" dir="ltr" + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'end'; + ctx.fillText('DD', 100, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.end.rtl + desc: textAlign end with rtl is the left edge + testing: + - 2d.text.align.left + - 2d.text.draw.direction + fonts: + - CanvasTest + canvas: width="100" height="50" dir="rtl" + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'end'; + ctx.fillText('DD', 0, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.align.center + desc: textAlign center is the center of the em squares (not the bounding box) + testing: + - 2d.text.align.center + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'center'; + ctx.fillText('DD', 50, 37.5); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 95,5 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + @assert pixel 5,45 ==~ 0,255,0,255; + @assert pixel 95,45 ==~ 0,255,0,255; + }), 500); + expected: green + + +- name: 2d.text.draw.space.basic + desc: U+0020 is rendered the correct size (1em wide) + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('E EE', -100, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.space.collapse.space + desc: Space characters are converted to U+0020, and collapsed (per CSS) + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('E EE', -100, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.space.collapse.other + desc: Space characters are converted to U+0020, and collapsed (per CSS) + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('E \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dEE', -100, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo + @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo + }), 500); + expected: green + +- name: 2d.text.draw.space.collapse.nonspace + desc: Non-space characters are not converted to U+0020 and collapsed + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText('E\x0b EE', -150, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.space.collapse.start + desc: Space characters at the start of a line are collapsed (per CSS) + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillText(' EE', 0, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo + @assert pixel 75,25 ==~ 0,255,0,255; + }), 500); + expected: green + +- name: 2d.text.draw.space.collapse.end + desc: Space characters at the end of a line are collapsed (per CSS) + testing: + - 2d.text.draw.spaces + fonts: + - CanvasTest + code: | + ctx.font = '50px CanvasTest'; + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.textAlign = 'right'; + ctx.fillText('EE ', 100, 37.5); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo + }), 500); + expected: green + + + + +- name: 2d.text.measure.width.basic + testing: + - 2d.text.measure + fonts: + - CanvasTest + code: | + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.font = '50px CanvasTest'; + @assert ctx.measureText('A').width === 50; + @assert ctx.measureText('AA').width === 100; + @assert ctx.measureText('ABCD').width === 200; + + ctx.font = '100px CanvasTest'; + @assert ctx.measureText('A').width === 100; + }), 500); + +- name: 2d.text.measure.width.empty + desc: The empty string has zero width + testing: + - 2d.text.measure + fonts: + - CanvasTest + code: | + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.font = '50px CanvasTest'; + @assert ctx.measureText("").width === 0; + }), 500); + +- name: 2d.text.measure.width.space + desc: Space characters are converted to U+0020 and collapsed (per CSS) + testing: + - 2d.text.measure.spaces + fonts: + - CanvasTest + code: | + deferTest(); + step_timeout(t.step_func_done(function () { + ctx.font = '50px CanvasTest'; + @assert ctx.measureText('A B').width === 150; + @assert ctx.measureText('A B').width === 150; @moz-todo + @assert ctx.measureText('A \x09\x0a\x0c\x0d \x09\x0a\x0c\x0dB').width === 150; @moz-todo + @assert ctx.measureText('A \x0b B').width >= 200; + + @assert ctx.measureText(' AB').width === 100; @moz-todo + @assert ctx.measureText('AB ').width === 100; @moz-todo + }), 500); + +# TODO: shadows, alpha, composite, clip
diff --git a/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/tools/generate.py b/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/tools/generate.py new file mode 100644 index 0000000..8e06f00 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/WebCryptoAPI/tools/generate.py
@@ -0,0 +1,76 @@ +# script to generate the generateKey tests + +import os + +here = os.path.dirname(__file__) + +successes_html = """<!DOCTYPE html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<title>WebCryptoAPI: generateKey() Successful Calls</title> +<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com"> +<link rel="help" href="https://www.w3.org/TR/WebCryptoAPI/#dfn-SubtleCrypto-method-generateKey"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="/WebCryptoAPI/util/helpers.js"></script> +<script src="successes.js"></script> + +<h1>generateKey Tests for Good Parameters</h1> +<p> + <strong>Warning!</strong> RSA key generation is intrinsically + very slow, so the related tests can take up to + several minutes to complete, depending on browser! +</p> + +<div id="log"></div> +<script> +run_test([%s]); +</script>""" + +failures_html = """<!DOCTYPE html> +<meta charset=utf-8> +<meta name="timeout" content="long"> +<title>WebCryptoAPI: generateKey() for Failures</title> +<link rel="author" title="Charles Engelke" href="mailto:w3c@engelke.com"> +<link rel="help" href="https://www.w3.org/TR/WebCryptoAPI/#dfn-SubtleCrypto-method-generateKey"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<script src="/WebCryptoAPI/util/helpers.js"></script> +<script src="failures.js"></script> + +<h1>generateKey Tests for Bad Parameters</h1> + +<div id="log"></div> +<script> +run_test([%s]); +</script> +""" + +successes_worker = """// META: timeout=long +importScripts("/resources/testharness.js"); +importScripts("../util/helpers.js"); +importScripts("successes.js"); + +run_test([%s]); +done();""" + +failures_worker = """// META: timeout=long +importScripts("/resources/testharness.js"); +importScripts("../util/helpers.js"); +importScripts("failures.js"); +run_test([%s]); +done();""" + +names = ["AES-CTR", "AES-CBC", "AES-GCM", "AES-KW", "HMAC", "RSASSA-PKCS1-v1_5", + "RSA-PSS", "RSA-OAEP", "ECDSA", "ECDH"] + +for filename_pattern, template in [("test_successes_%s.html", successes_html), + ("test_failures_%s.html", failures_html), + ("successes_%s.worker.js", successes_worker), + ("failures_%s.worker.js", failures_worker)]: + for name in names: + path = os.path.join(here, os.pardir, "generateKey", filename_pattern % name) + with open(path, "w") as f: + f.write(template % '"%s"' % name)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/ahem-generate-table.py b/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/ahem-generate-table.py new file mode 100644 index 0000000..29b4f0e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/ahem-generate-table.py
@@ -0,0 +1,102 @@ +from __future__ import print_function, unicode_literals + +import itertools +import unicodedata + +from fontTools.ttLib import TTFont + +try: + chr(0x100) +except ValueError: + chr = unichr + +def grouper(n, iterable): + """ + >>> list(grouper(3, 'ABCDEFG')) + [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']] + """ + iterable = iter(iterable) + return iter(lambda: list(itertools.islice(iterable, n)), []) + +ttf = TTFont("../../css/fonts/ahem/ahem.ttf") + +chars = {char for table in ttf['cmap'].tables for char in table.cmap.keys()} + +# exclude chars that can't be represented as HTML numeric character refs +chars = chars - (set(range(0x80, 0x9F+1)) | {0x00}) + +chars_sorted = sorted(chars) + +per_row = 17 + + +def build_header(is_test): + rv = [] + + rv.append(""" +<!doctype html> +<title>Ahem checker</title>""") + + if is_test: + rv.append(""" +<link rel="match" href="ahem-ref.html">""") + + rv.append(""" +<style>""") + + if not is_test: + rv.append(""" +@font-face { + font-family: Ahem; + src: url("../css/fonts/ahem/ahem.ttf"); +}""") + + rv.append(""" +* { + padding: 0; + margin: 0; + border: none; +} + +table { + font: 15px/1 Ahem; + border-collapse: separate; + border-spacing: 1px; + table-layout: fixed; +} + +td { + width: 34px; +} +</style> +""") + + return "".join(rv) + + +def build_table(): + rv = [] + + rv.append("<table>\n") + for row in grouper(per_row, chars_sorted): + rv.append(" " * 4 + "<tr>\n") + for codepoint in row: + assert codepoint <= 0xFFFF + try: + name = unicodedata.name(chr(codepoint)) + except ValueError: + rv.append(" " * 8 + "<td>&#x%04X;x <!-- U+%04X -->\n" % (codepoint, codepoint)) + else: + rv.append(" " * 8 + "<td>&#x%04X;x <!-- U+%04X: %s -->\n" % (codepoint, codepoint, name)) + rv.append("</table>\n") + + return "".join(rv) + + +with open("../ahem.html", "w") as f1: + f1.write(build_header(True)) + f1.write(build_table()) + +with open("../ahem-ref.html", "w") as f1: + f1.write(build_header(False)) + f1.write(build_table())
diff --git a/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/build.sh b/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/build.sh new file mode 100755 index 0000000..d40f63a7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/assumptions/tools/build.sh
@@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -ex + +cd "${0%/*}" +virtualenv -p python .virtualenv +.virtualenv/bin/pip install fonttools==3.13.1 +.virtualenv/bin/python ahem-generate-table.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/.gitignore b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/.gitignore new file mode 100644 index 0000000..3c3629e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/.gitignore
@@ -0,0 +1 @@ +node_modules
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/README.md b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/README.md new file mode 100644 index 0000000..cc7cc5b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/README.md
@@ -0,0 +1,23 @@ +Generators +========== + +This directory contains scripts to generate some tests. + +## Setup + +1. Install node.js. +2. Change the current directory to this directory. +3. Type the following commands: +``` +npm install +``` +4. (optional) Install gulp globally so it'll be on your path: +``` +sudo npm install -g gulp +``` + +## Generate Test Files + +``` +gulp +```
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/gulpfile.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/gulpfile.js new file mode 100644 index 0000000..1eb6ecf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/gulpfile.js
@@ -0,0 +1,79 @@ +'use strict'; + +const testdir = "../.."; +const refdir = "../../reference"; + +var browserSync = null; +var gulp = require("gulp"); +var gutil = require('gulp-util'); +var ejs = require("gulp-ejs"); +var rename = require("gulp-rename"); + +gulp.task("default", [ + "snap-width", +]); + +var snapWidthFiles = []; +[["inline"], ["block"], ["table"]].forEach(contentTypes => { + ["available", "fixed", "max"].forEach(widthType => { + snapWidthFiles.push({ + name: "snap-width-" + contentTypes.join("-") + "-in-" + widthType + "-001", + contentTypes: contentTypes, + widthType: widthType, + }); + }); + snapWidthFiles.push({ + name: "snap-width-" + contentTypes.join("-") + "-001", + contentTypes: contentTypes, + isReference: true, + }); +}); + +gulp.task("snap-width", function () { + return generateFiles(snapWidthFiles); +}); + +function generateFiles(files) { + return generateFile(files[0]) + .on("end", function () { + if (files.length > 1) + return generateFiles(files.slice(1)); + }); +} + +function generateFile(options) { + options.isReference = options.isReference || false; + options.destname = options.name + ".html"; + options.destdir = options.isReference ? refdir : testdir; + gutil.log("Generating", options.destname); + return gulp.src("snap-width.ejs") + .pipe(ejs(options)) + .pipe(rename(options.destname)) + .pipe(gulp.dest(options.destdir)); +} + +function extend(obj, props) { + for (var p in props) + if (props.hasOwnProperty(p)) + obj[p] = props[p]; + return obj; +} + +gulp.task("test", ["browser-sync", "watch"]); + +gulp.task("watch", function () { + gulp.watch("snap-width.ejs", ["snap-width"]); +}); + +gulp.task("browser-sync", function () { + if (!browserSync) + browserSync = require("browser-sync"); + browserSync({ + server: { + baseDir: "../../..", + directory: true, + }, + files: [testdir + "/*", refdir + "/*"], + startPath: "css-snap-size-1/", + }); +});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/package.json b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/package.json new file mode 100644 index 0000000..93f5c13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/package.json
@@ -0,0 +1,18 @@ +{ + "name": "generators", + "version": "1.0.0", + "description": "Generators ==========", + "main": "gulpfile.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "browser-sync": "^2.11.1", + "ejs": "^2.4.1", + "gulp": "^3.9.1", + "gulp-ejs": "^2.1.1", + "gulp-rename": "^1.2.2" + } +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/snap-width.ejs b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/snap-width.ejs new file mode 100644 index 0000000..d8d5e828 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-rhythm-1/tools/generators/snap-width.ejs
@@ -0,0 +1,96 @@ +<!DOCTYPE html> +<title>CSS Snap Size: snap-width</title> +<% if (!isReference) { +%><link rel="help" href="https://drafts.csswg.org/css-snap-size/#snap-width"> +<link rel="match" href="reference/snap-width-<%= contentType %>-001.html"> +<meta name="assert" content="This test asserts the snap-width property rounds down the box width."> +<meta name="flags" content="ahem"> +<% } %><link rel="author" title="Koji Ishii" href="kojiishi@gmail.com"> +<% +var styles = ""; +if (!isReference) { + switch (widthType) { + case "available": + styles = ` +.container { width: 20.5em; } +.container.border, .container.padding { width: 21.3em; } +.container.border.padding { width: 22.1em; } +.test { + snap-width: 1em; + text-align: right; +}`; + break; + case "fixed": + styles = ` +.test { + snap-width: 1em; + text-align: right; + width: 20.5em; +}`; + break; + case "max": + styles = ` +.test { + snap-width: 1em; + text-align: right; + max-width: 20.5em; +}`; + break; + default: + console.assert(false, "Unknown widthType:", widthType); + } +} + +var contentHTML = "XXXXXXXXXX XXXXXXXXX"; +for (var contentType of contentTypes) { + switch (contentType) { + case "block": + contentHTML= `<div>${contentHTML}</div>`; + break; + case "table": + contentHTML= `<table width="100%"><tr><td>${contentHTML}</td></tr></table>`; + styles += ` +table { border-spacing: 0; } +td { padding: 0; }`; + break; + case "inline": + break; + default: + console.assert(false, "Unknown contentType:", contentType); + } +} +%><style> +.container { + font-family: Ahem; + font-size: 32px; + line-height: 1; +} +.container > div { + margin: .5em 0; +} +.border > div { + border-left: .4em transparent solid; + border-right: .4em transparent solid; +} +.padding > div { + padding: 0 .4em; +} +<%= styles %> +.ref { + white-space: pre; /* make sure the line does not wrap */ + width: 20em; +} +</style> +<body> +<p class="instructions">Test passes if each pair of boxes are the same, + including how they look, widths, and horizontal positions. +<% [[], ["border"], ["padding"], ["border", "padding"]].forEach(function (containerClassList) { + containerClassList.push("container"); +%> +<div class="<%= containerClassList.join(" ") %>"> +<% [isReference ? "ref" : "test", "ref"].forEach(function (testClass) { +%> <div class="<%=testClass%>"><%- contentHTML %></div> +<% }); +%></div> +<% }); +%></body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/.gitignore b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/.gitignore new file mode 100644 index 0000000..3c3629e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/.gitignore
@@ -0,0 +1 @@ +node_modules
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/README.md b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/README.md new file mode 100644 index 0000000..7c58489 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/README.md
@@ -0,0 +1,25 @@ +Generators +========== + +Following test files are generated by the programs in this directory: +* orthogonal-parent-shrink-to-fit-001 +* text-orientation-script-001 + +## Setup + +1. Install node.js. +2. Change the current directory to this directory. +3. Type the following commands: +``` +npm install +``` +4. (optional) Install gulp globally so it'll be on your path: +``` +sudo npm install -g gulp +``` + +## Generate Test Files + +``` +gulp +```
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/gulpfile.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/gulpfile.js new file mode 100644 index 0000000..0ebd13c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/gulpfile.js
@@ -0,0 +1,97 @@ +'use strict'; + +var browserSync = null; +var gulp = require("gulp"); +var ejs = require("gulp-ejs"); +var rename = require("gulp-rename"); +var minimist = require('minimist'); +var argv = minimist(process.argv.slice(2)); + +gulp.task("default", [ + "orthogonal-parent-shrink-to-fit", + "text-orientation", +]); + +gulp.task("test", ["browser-sync", "watch"]); + +gulp.task("watch", function () { + gulp.watch("orthogonal-parent-shrink-to-fit.ejs", ["orthogonal-parent-shrink-to-fit"]); + gulp.watch( + [ + "text-orientation-ref.ejs", + "text-orientation-script.ejs", + "text-orientation-generator.js", + "unicode-data.js", + ], + ["text-orientation"]) + .on("change", file => delete require.cache[require.resolve(file.path)]); +}); + +gulp.task("browser-sync", function () { + if (!browserSync) + browserSync = require("browser-sync"); + browserSync({ + server: { + baseDir: "../../..", + directory: true, + }, + startPath: "css-writing-modes-3/", + }); +}); + +function reload() { + if (browserSync) + browserSync.reload(); +} + +gulp.task("server", function () { + var connect = require("connect"); + var serveIndex = require("serve-index"); + var serveStatic = require("serve-static"); + var directory = "../../.."; + var port = 8000; + connect() + .use(serveIndex(directory)) + .use(serveStatic(directory)) + .listen(port); + console.log("Listening on port " + port); +}) + +gulpTaskFromTemplateWithAffixes("orthogonal-parent-shrink-to-fit", "-001", -1, 24); + +gulp.task("text-orientation", function () { + var orientation = require("./text-orientation-generator.js"); + return Promise.all([ + orientation.generate(argv), + orientation.generateRefTest(argv), + ]).then(reload); +}); + +gulp.task("update", function () { + const unicodeData = require('./unicode-data.js'); + unicodeData.copyToLocal(); +}); + +function gulpTaskFromTemplateWithAffixes(name, suffix, min, lim) { + if (argv.nocombo && min < 0) + min = 0; + if (argv.nochild && lim > 0) + lim = 0; + gulp.task(name, function () { + for (var i = min; i < lim; ++i) { + gulp.src(name + ".ejs") + .pipe(ejs({ index: i })) + .pipe(rename(name + suffix + affixFromIndex(i) + ".html")) + .pipe(gulp.dest("../..")); + } + reload(); + }); +} + +function affixFromIndex(index) { + if (index < 0) + return ""; + if (index >= 26) + throw new Error("Affix index too large (" + index + ")"); + return String.fromCharCode("a".charCodeAt(0) + index); +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/orthogonal-parent-shrink-to-fit.ejs b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/orthogonal-parent-shrink-to-fit.ejs new file mode 100644 index 0000000..987c4a1f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/orthogonal-parent-shrink-to-fit.ejs
@@ -0,0 +1,128 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<% +var testlist = []; +var outers = [ + ["inline-block", '<div class="inline-block">', '</div><span class="next">ZZ</span>'], + ["float", '<div class="float">', '</div><span class="next">ZZ</span>'], + ["table-cell", '<table><tr><td>', '</td><td class="next">ZZ</td></tr></table>']]; +var middles = [ + null, + ["inline-block", '<div class="inline-block">', '</div>']]; +var targets = [ + ["block", '<div class="target">HH</div>'], + ["inline", '<span class="target">HH</span>'], + ["block with borders", '<div class="target border">HHH</div>'], + ["inline with borders", '<span class="target border">HHH</span>']]; +for (var outer of outers) { + for (var middle of middles) { + for (var target of targets) { + var title = target[0]; + var html = target[1]; + if (middle) { + title += " in " + middle[0]; + html = middle[1] + html + middle[2]; + } + title = "Shrink-to-fit " + outer[0] + " with a child of orthogonal " + title; + html = outer[1] + html + outer[2]; + testlist.push([title, html]); + } + } +} +var min, limit, title; +if (index < 0) { + min = 0; + limit = testlist.length; + title = "Shrink-to-fit with orthogonal children" +} else { + min = index; + limit = index + 1; + title = testlist[index][0]; +} +%><title>CSS Writing Modes Test: <%= title %></title> +<link rel="help" href="http://www.w3.org/TR/css-writing-modes-3/#orthogonal-flows" title="7.3. Orthogonal Flows"> +<meta name="assert" content="<%= title %>"> +<meta name="flags" content="ahem dom<%= index < 0 ? ' combo' : ''%>"> +<link rel="author" title="Koji Ishii" href="mailto:kojiishi@gmail.com"> +<link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/"> <!-- 2015-12-23 --> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +.test { + border:thin solid; + font:20px/1 Ahem; +} +.target { + color:blue; + height:3em; /* height: 3em is not required. IE11 and Edge12 compute height to ICB height if + not set. We want the test to focus exclusively on shrink-to-fit algorithm. */ + writing-mode:vertical-rl; +} +.border { + border-right:blue solid .5em; +} +.next { + color:orange; +} +.inline-block { + display:inline-block; +} +.float { + float:left; +} +h3 { + clear:both; +} +h3.fail { + color:red; +} +table { + border-spacing:0px; +} +td { + padding:0px; +} +</style> +<div id="log"></div> +<div id="container"> +<p>Test passes if the X-position of the <b>left</b> edge of the orange box and the <b>right</b> edge of the blue box are the same. +<p>If script is enabled, there should be one or more PASS and no FAIL. +<% for (var i = min; i < limit; ++i) { + var test = testlist[i]; +%><h3><%= (i + 1) + ": " + test[0] %></h3> +<div class="test"> + <%- test[1] %> +</div> +<% } %></div> +<script> +if (window.location.search == "?wait") { + console.log("Sleeping 5 secs for debug"); + setup({explicit_done:true}); + window.setTimeout(run, 5000); +} else { + run(); +} + +function run() { + Array.prototype.forEach.call(document.querySelectorAll(".test"), function (node) { + var title = node.previousElementSibling.textContent; + test(function () { + try { + var targetNode = node.querySelector(".target"); + var fontSize = parseFloat(getComputedStyle(targetNode).fontSize); + var targetBounds = targetNode.getBoundingClientRect(); + assert_less_than_equal(targetBounds.width, fontSize * 2.01, "writing-mode is vertical") + var nextNode = node.querySelector(".next"); + var nextBounds = nextNode.getBoundingClientRect(); + assert_equals(nextBounds.left - targetBounds.right, 0, "the left edge of the orange box touches the right edge of the blue box"); + } catch (e) { + node.previousElementSibling.classList.add("fail"); + throw e; + } + }, title); + }); + if (window.testRunner) + container.style.display = "none"; + done(); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/package.json b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/package.json new file mode 100644 index 0000000..8046cf4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/package.json
@@ -0,0 +1,23 @@ +{ + "name": "generators", + "version": "1.0.0", + "description": "", + "main": "gulpfile.js", + "dependencies": {}, + "devDependencies": { + "browser-sync": "^2.10.1", + "connect": "^3.4.0", + "ejs": "^2.3.1", + "gulp": "^3.8.11", + "gulp-ejs": "^1.1.0", + "gulp-rename": "^1.2.2", + "minimist": "^1.1.1", + "serve-index": "^1.7.2", + "serve-static": "^1.10.0" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-generator.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-generator.js new file mode 100644 index 0000000..8fe9115 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-generator.js
@@ -0,0 +1,190 @@ +// This is a node.js program to generate text-orientation-script test files. +'use strict'; + +(function (exports) { + var ejs = require("ejs"); + var fs = require("fs"); + var unicodeData = require("./unicode-data.js"); + + class Generator { + constructor(rangesByVO, gc, blocks) { + this.rangesByVO = rangesByVO; + this.gc = gc; + this.blocks = blocks; + this.charactersPerLine = 32; + } + generate(argv) { + var codePointsByVO = {}; + var gc = this.gc; + var skipFunc = this.createSkipFunc(argv.noskip); + for (var value in this.rangesByVO) + codePointsByVO[value] = unicodeData.codePointsFromRanges(this.rangesByVO[value], skipFunc); + + this.codePointsByVO = codePointsByVO; + var template = fs.readFileSync("text-orientation-script.ejs", "utf-8"); + this.template = ejs.compile(template); + + if (!argv.nocombo) + this.generateFile(); + if (argv.nochild) + return; + + var pageSize = this.charactersPerLine * 64; + var fileIndex = 0; + for (var vo in codePointsByVO) { + var codePoints = codePointsByVO[vo]; + var limit = codePoints.length; + var pages = Math.ceil(limit / pageSize); + for (var min = 0, page = 1; min < limit; ++page, ++fileIndex) { + var nextLimit = Math.min(limit, min + pageSize); + this.codePointsByVO = {}; + this.codePointsByVO[vo] = codePoints.slice(min, nextLimit); + this.generateFile(vo, fileIndex, page, pages); + min = nextLimit; + } + } + } + generateFile(vo, fileIndex, page, pages) { + var path = "../../text-orientation-script-001"; + this.title = "Test orientation of characters"; + this.flags = "dom"; + // if (fileIndex) + // path += "-" + padZero(fileIndex, 3); + if (fileIndex === undefined) + this.flags += " combo"; + else + path += affixFromIndex(fileIndex); + if (vo) { + this.title += " where vo=" + vo; + var codePoints = this.codePointsByVO[vo]; + var rangeText = codePoints.length + " code points in U+" + + unicodeData.toHex(codePoints[0]) + "-" + + unicodeData.toHex(codePoints[codePoints.length - 1]); + if (page && pages > 1) + rangeText = "#" + page + "/" + pages + ", " + rangeText; + this.title += " (" + rangeText + ")"; + } + path += ".html"; + console.log("Writing " + path + ": " + this.title); + var output = fs.openSync(path, "w"); + fs.writeSync(output, this.template(this)); + fs.closeSync(output); + } + generateRefTest() { + var template = fs.readFileSync("text-orientation-ref.ejs", "utf-8"); + this.template = ejs.compile(template); + this.codePointRanges = [ + [0x0020, 0x007E], + [0x3000, 0x30FF], + [0x4E00, 0x4E1F], + [0xFF01, 0xFF60], + ]; + var writingModes = [ + { key: "vlr", value: "vertical-lr" }, + { key: "vrl", value: "vertical-rl" }, + ]; + var voByCodePoint = unicodeData.arrayFromRangesByValue(this.rangesByVO); + var R = 0x0041, U = 0x56FD; + var textOrientations = [ + { value: "mixed", ref: function (ch) { return voByCodePoint[ch] == "R" ? R : U; } }, + { value: "sideways", ref: function (ch) { return R; } }, + { value: "upright", ref: function (ch) { return U; } }, + ]; + var self = this; + writingModes.forEach(function (writingMode) { + self.writingMode = writingMode.value; + textOrientations.forEach(function (textOrientation) { + self.textOrientation = textOrientation.value; + self.title = "writing-mode: " + self.writingMode + "; text-orientation: " + self.textOrientation; + var key = textOrientation.value + "-" + writingMode.key; + self.generateRefTestFile(key, false); + self.generateRefTestFile(key, true, textOrientation.ref); + }); + }); + } + generateRefTestFile(key, isReference, mapCodePointForRendering) { + var name = "text-orientation-" + key + "-100"; + var path = name + ".html"; + var reference = name + "-ref.html"; + if (isReference) { + path = "../../" + reference; + this.reference = null; + } else { + path = "../../" + path; + this.reference = reference; + } + console.log("Writing " + path + ": " + this.title); + var skipFunc0 = this.createSkipFunc(true); + // Workaround CSS test harness bug that double-escape < and >. + var skipFunc = c => c == 0x3C || c == 0x3E || skipFunc0(c); + this.codePointsFromRangeForRendering = mapCodePointForRendering + ? range => unicodeData.codePointsFromRanges(range, skipFunc).map(mapCodePointForRendering) + : range => unicodeData.codePointsFromRanges(range, skipFunc); + var output = fs.openSync(path, "w"); + fs.writeSync(output, this.template(this)); + fs.closeSync(output); + } + headingFromRange(range) { + return "U+" + unicodeData.toHex(range[0]) + "-" + unicodeData.toHex(range[range.length - 1]); + } + createSkipFunc(noSkip) { + var gc = this.gc; + function skipCombiningMarks(code) { + return unicodeData.isSkipGeneralCategory(code, gc) || + code == 0x0E33 || // Thai U+0E33 is class AM: https://www.microsoft.com/typography/OpenTypeDev/thai/intro.htm + code == 0x0EB3; // Lao U+0EB3 is class AM: https://www.microsoft.com/typography/OpenTypeDev/lao/intro.htm + } + if (noSkip) + return skipCombiningMarks; + return function (code) { return unicodeData.isCJKMiddle(code) || skipCombiningMarks(code); }; + } + splitCodePointsByBlocks(codePoints) { + return unicodeData.splitCodePoints(codePoints, this.blocks); + } + linesFromCodePoints(codePoints) { + var lines = []; + var limit = codePoints.length; + for (var index = 0; index < limit; ) { + var lineLimit = Math.min(limit, index + this.charactersPerLine); + var line = []; + for (; index < lineLimit; ++index) + unicodeData.encodeUtf16(codePoints[index], line); + lines.push(String.fromCharCode.apply(String, line)); + } + return lines; + } + } + + function affixFromIndex(index) { + if (index < 0) + return ""; + if (index >= 26) + throw new Error("Affix index too large (" + index + ")"); + return String.fromCharCode("a".charCodeAt(0) + index); + } + + function createGenerator(argv) { + var promise = new Promise(function(resolve, reject) { + Promise.all([ + unicodeData.get(unicodeData.url.vo, unicodeData.formatAsRangesByValue), + unicodeData.get(unicodeData.url.gc), + unicodeData.get(unicodeData.url.blocks), + ]).then(function (results) { + var generator = new Generator(results[0], results[1], results[2]); + generator.prefix = argv.prefix ? "-" + argv.prefix + "-" : ""; + resolve(generator); + }); + }); + return promise; + } + + exports.generate = function (argv) { + return createGenerator(argv) + .then(generator => generator.generate(argv)); + }; + + exports.generateRefTest = function (argv) { + return createGenerator(argv) + .then(generator => generator.generateRefTest(argv)); + }; +})(module.exports);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-ref.ejs b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-ref.ejs new file mode 100644 index 0000000..89cd382d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-ref.ejs
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Writing Modes Test: <%= title %>.</title> +<% if (reference) { +%><link rel="match" href="<%= reference %>"> +<link rel="help" href="http://www.w3.org/TR/css-writing-modes-3/#text-orientation"> +<% } +%><link rel="author" title="Koji Ishii" href="mailto:kojiishi@gmail.com"> +<style> +@font-face { + font-family: "orientation"; + src: url("support/adobe-fonts/CSSHWOrientationTest.otf"); +} +html { + <%= prefix %>writing-mode: <%= writingMode %>; +} +.test { + font: 20px/1 "orientation"; + height: 17em; + <%= prefix %>text-orientation: <%= textOrientation %>; +} +.line { + white-space: pre; +} +</style> +<body> +<div id="container"> +<% for (var range of codePointRanges) { +%><div><%= headingFromRange(range) %><div class="test"> +<% var codePoints = codePointsFromRangeForRendering(range); + for (var line of linesFromCodePoints(codePoints)) { +%><div class="line"><%= line %></div> +<% } +%></div></div> +<% } %></div> +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-script.ejs b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-script.ejs new file mode 100644 index 0000000..dd96af25 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/text-orientation-script.ejs
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Writing Modes Test: <%= title %>.</title> +<link rel="help" href="http://www.w3.org/TR/css-writing-modes-3/#text-orientation"> +<meta name="assert" content="<%= title %>"> +<meta name="flags" content="<%= flags %>"> +<link rel="author" title="Koji Ishii" href="mailto:kojiishi@gmail.com"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@font-face { + font-family: "orientation"; + src: url("support/adobe-fonts/CSSHWOrientationTest.otf"); +} +.test { + font: 16px/1 "orientation"; + height: 17em; + <%= prefix %>writing-mode: vertical-rl; +} +.line { + white-space: pre; +} +.U { + <%= prefix %>text-orientation: upright; +} +.R { + <%= prefix %>text-orientation: sideways; +} +#details { + margin: 1em .5em; +} +summary { + font-size: 1.2em; + font-weight: bold; + margin-top: .5em; +} +</style> +<div id="log"></div> +<div id="details"></div> +<div id="container"> +<% for (var vo in codePointsByVO) { +%><div data-vo="<%= vo %>" class="test"> +<% for (var codePointsOfBlock of splitCodePointsByBlocks(codePointsByVO[vo])) { +%><div data-block="<%= codePointsOfBlock[1] %>"> +<% for (var line of linesFromCodePoints(codePointsOfBlock[0])) { +%><div class="line"><%= line %></div> +<% } +%></div> +<% } +%></div> +<% } +%></div> +<script src="support/text-orientation.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/Blocks.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/Blocks.txt new file mode 100644 index 0000000..74c41e5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/Blocks.txt
@@ -0,0 +1,309 @@ +# Blocks-9.0.0.txt +# Date: 2016-02-05, 23:48:00 GMT [KW] +# © 2016 Unicode®, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Format: +# Start Code..End Code; Block Name + +# ================================================ + +# Note: When comparing block names, casing, whitespace, hyphens, +# and underbars are ignored. +# For example, "Latin Extended-A" and "latin extended a" are equivalent. +# For more information on the comparison of property values, +# see UAX #44: http://www.unicode.org/reports/tr44/ +# +# All block ranges start with a value where (cp MOD 16) = 0, +# and end with a value where (cp MOD 16) = 15. In other words, +# the last hexadecimal digit of the start of range is ...0 +# and the last hexadecimal digit of the end of range is ...F. +# This constraint on block ranges guarantees that allocations +# are done in terms of whole columns, and that code chart display +# never involves splitting columns in the charts. +# +# All code points not explicitly listed for Block +# have the value No_Block. + +# Property: Block +# +# @missing: 0000..10FFFF; No_Block + +0000..007F; Basic Latin +0080..00FF; Latin-1 Supplement +0100..017F; Latin Extended-A +0180..024F; Latin Extended-B +0250..02AF; IPA Extensions +02B0..02FF; Spacing Modifier Letters +0300..036F; Combining Diacritical Marks +0370..03FF; Greek and Coptic +0400..04FF; Cyrillic +0500..052F; Cyrillic Supplement +0530..058F; Armenian +0590..05FF; Hebrew +0600..06FF; Arabic +0700..074F; Syriac +0750..077F; Arabic Supplement +0780..07BF; Thaana +07C0..07FF; NKo +0800..083F; Samaritan +0840..085F; Mandaic +08A0..08FF; Arabic Extended-A +0900..097F; Devanagari +0980..09FF; Bengali +0A00..0A7F; Gurmukhi +0A80..0AFF; Gujarati +0B00..0B7F; Oriya +0B80..0BFF; Tamil +0C00..0C7F; Telugu +0C80..0CFF; Kannada +0D00..0D7F; Malayalam +0D80..0DFF; Sinhala +0E00..0E7F; Thai +0E80..0EFF; Lao +0F00..0FFF; Tibetan +1000..109F; Myanmar +10A0..10FF; Georgian +1100..11FF; Hangul Jamo +1200..137F; Ethiopic +1380..139F; Ethiopic Supplement +13A0..13FF; Cherokee +1400..167F; Unified Canadian Aboriginal Syllabics +1680..169F; Ogham +16A0..16FF; Runic +1700..171F; Tagalog +1720..173F; Hanunoo +1740..175F; Buhid +1760..177F; Tagbanwa +1780..17FF; Khmer +1800..18AF; Mongolian +18B0..18FF; Unified Canadian Aboriginal Syllabics Extended +1900..194F; Limbu +1950..197F; Tai Le +1980..19DF; New Tai Lue +19E0..19FF; Khmer Symbols +1A00..1A1F; Buginese +1A20..1AAF; Tai Tham +1AB0..1AFF; Combining Diacritical Marks Extended +1B00..1B7F; Balinese +1B80..1BBF; Sundanese +1BC0..1BFF; Batak +1C00..1C4F; Lepcha +1C50..1C7F; Ol Chiki +1C80..1C8F; Cyrillic Extended-C +1CC0..1CCF; Sundanese Supplement +1CD0..1CFF; Vedic Extensions +1D00..1D7F; Phonetic Extensions +1D80..1DBF; Phonetic Extensions Supplement +1DC0..1DFF; Combining Diacritical Marks Supplement +1E00..1EFF; Latin Extended Additional +1F00..1FFF; Greek Extended +2000..206F; General Punctuation +2070..209F; Superscripts and Subscripts +20A0..20CF; Currency Symbols +20D0..20FF; Combining Diacritical Marks for Symbols +2100..214F; Letterlike Symbols +2150..218F; Number Forms +2190..21FF; Arrows +2200..22FF; Mathematical Operators +2300..23FF; Miscellaneous Technical +2400..243F; Control Pictures +2440..245F; Optical Character Recognition +2460..24FF; Enclosed Alphanumerics +2500..257F; Box Drawing +2580..259F; Block Elements +25A0..25FF; Geometric Shapes +2600..26FF; Miscellaneous Symbols +2700..27BF; Dingbats +27C0..27EF; Miscellaneous Mathematical Symbols-A +27F0..27FF; Supplemental Arrows-A +2800..28FF; Braille Patterns +2900..297F; Supplemental Arrows-B +2980..29FF; Miscellaneous Mathematical Symbols-B +2A00..2AFF; Supplemental Mathematical Operators +2B00..2BFF; Miscellaneous Symbols and Arrows +2C00..2C5F; Glagolitic +2C60..2C7F; Latin Extended-C +2C80..2CFF; Coptic +2D00..2D2F; Georgian Supplement +2D30..2D7F; Tifinagh +2D80..2DDF; Ethiopic Extended +2DE0..2DFF; Cyrillic Extended-A +2E00..2E7F; Supplemental Punctuation +2E80..2EFF; CJK Radicals Supplement +2F00..2FDF; Kangxi Radicals +2FF0..2FFF; Ideographic Description Characters +3000..303F; CJK Symbols and Punctuation +3040..309F; Hiragana +30A0..30FF; Katakana +3100..312F; Bopomofo +3130..318F; Hangul Compatibility Jamo +3190..319F; Kanbun +31A0..31BF; Bopomofo Extended +31C0..31EF; CJK Strokes +31F0..31FF; Katakana Phonetic Extensions +3200..32FF; Enclosed CJK Letters and Months +3300..33FF; CJK Compatibility +3400..4DBF; CJK Unified Ideographs Extension A +4DC0..4DFF; Yijing Hexagram Symbols +4E00..9FFF; CJK Unified Ideographs +A000..A48F; Yi Syllables +A490..A4CF; Yi Radicals +A4D0..A4FF; Lisu +A500..A63F; Vai +A640..A69F; Cyrillic Extended-B +A6A0..A6FF; Bamum +A700..A71F; Modifier Tone Letters +A720..A7FF; Latin Extended-D +A800..A82F; Syloti Nagri +A830..A83F; Common Indic Number Forms +A840..A87F; Phags-pa +A880..A8DF; Saurashtra +A8E0..A8FF; Devanagari Extended +A900..A92F; Kayah Li +A930..A95F; Rejang +A960..A97F; Hangul Jamo Extended-A +A980..A9DF; Javanese +A9E0..A9FF; Myanmar Extended-B +AA00..AA5F; Cham +AA60..AA7F; Myanmar Extended-A +AA80..AADF; Tai Viet +AAE0..AAFF; Meetei Mayek Extensions +AB00..AB2F; Ethiopic Extended-A +AB30..AB6F; Latin Extended-E +AB70..ABBF; Cherokee Supplement +ABC0..ABFF; Meetei Mayek +AC00..D7AF; Hangul Syllables +D7B0..D7FF; Hangul Jamo Extended-B +D800..DB7F; High Surrogates +DB80..DBFF; High Private Use Surrogates +DC00..DFFF; Low Surrogates +E000..F8FF; Private Use Area +F900..FAFF; CJK Compatibility Ideographs +FB00..FB4F; Alphabetic Presentation Forms +FB50..FDFF; Arabic Presentation Forms-A +FE00..FE0F; Variation Selectors +FE10..FE1F; Vertical Forms +FE20..FE2F; Combining Half Marks +FE30..FE4F; CJK Compatibility Forms +FE50..FE6F; Small Form Variants +FE70..FEFF; Arabic Presentation Forms-B +FF00..FFEF; Halfwidth and Fullwidth Forms +FFF0..FFFF; Specials +10000..1007F; Linear B Syllabary +10080..100FF; Linear B Ideograms +10100..1013F; Aegean Numbers +10140..1018F; Ancient Greek Numbers +10190..101CF; Ancient Symbols +101D0..101FF; Phaistos Disc +10280..1029F; Lycian +102A0..102DF; Carian +102E0..102FF; Coptic Epact Numbers +10300..1032F; Old Italic +10330..1034F; Gothic +10350..1037F; Old Permic +10380..1039F; Ugaritic +103A0..103DF; Old Persian +10400..1044F; Deseret +10450..1047F; Shavian +10480..104AF; Osmanya +104B0..104FF; Osage +10500..1052F; Elbasan +10530..1056F; Caucasian Albanian +10600..1077F; Linear A +10800..1083F; Cypriot Syllabary +10840..1085F; Imperial Aramaic +10860..1087F; Palmyrene +10880..108AF; Nabataean +108E0..108FF; Hatran +10900..1091F; Phoenician +10920..1093F; Lydian +10980..1099F; Meroitic Hieroglyphs +109A0..109FF; Meroitic Cursive +10A00..10A5F; Kharoshthi +10A60..10A7F; Old South Arabian +10A80..10A9F; Old North Arabian +10AC0..10AFF; Manichaean +10B00..10B3F; Avestan +10B40..10B5F; Inscriptional Parthian +10B60..10B7F; Inscriptional Pahlavi +10B80..10BAF; Psalter Pahlavi +10C00..10C4F; Old Turkic +10C80..10CFF; Old Hungarian +10E60..10E7F; Rumi Numeral Symbols +11000..1107F; Brahmi +11080..110CF; Kaithi +110D0..110FF; Sora Sompeng +11100..1114F; Chakma +11150..1117F; Mahajani +11180..111DF; Sharada +111E0..111FF; Sinhala Archaic Numbers +11200..1124F; Khojki +11280..112AF; Multani +112B0..112FF; Khudawadi +11300..1137F; Grantha +11400..1147F; Newa +11480..114DF; Tirhuta +11580..115FF; Siddham +11600..1165F; Modi +11660..1167F; Mongolian Supplement +11680..116CF; Takri +11700..1173F; Ahom +118A0..118FF; Warang Citi +11AC0..11AFF; Pau Cin Hau +11C00..11C6F; Bhaiksuki +11C70..11CBF; Marchen +12000..123FF; Cuneiform +12400..1247F; Cuneiform Numbers and Punctuation +12480..1254F; Early Dynastic Cuneiform +13000..1342F; Egyptian Hieroglyphs +14400..1467F; Anatolian Hieroglyphs +16800..16A3F; Bamum Supplement +16A40..16A6F; Mro +16AD0..16AFF; Bassa Vah +16B00..16B8F; Pahawh Hmong +16F00..16F9F; Miao +16FE0..16FFF; Ideographic Symbols and Punctuation +17000..187FF; Tangut +18800..18AFF; Tangut Components +1B000..1B0FF; Kana Supplement +1BC00..1BC9F; Duployan +1BCA0..1BCAF; Shorthand Format Controls +1D000..1D0FF; Byzantine Musical Symbols +1D100..1D1FF; Musical Symbols +1D200..1D24F; Ancient Greek Musical Notation +1D300..1D35F; Tai Xuan Jing Symbols +1D360..1D37F; Counting Rod Numerals +1D400..1D7FF; Mathematical Alphanumeric Symbols +1D800..1DAAF; Sutton SignWriting +1E000..1E02F; Glagolitic Supplement +1E800..1E8DF; Mende Kikakui +1E900..1E95F; Adlam +1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols +1F000..1F02F; Mahjong Tiles +1F030..1F09F; Domino Tiles +1F0A0..1F0FF; Playing Cards +1F100..1F1FF; Enclosed Alphanumeric Supplement +1F200..1F2FF; Enclosed Ideographic Supplement +1F300..1F5FF; Miscellaneous Symbols and Pictographs +1F600..1F64F; Emoticons +1F650..1F67F; Ornamental Dingbats +1F680..1F6FF; Transport and Map Symbols +1F700..1F77F; Alchemical Symbols +1F780..1F7FF; Geometric Shapes Extended +1F800..1F8FF; Supplemental Arrows-C +1F900..1F9FF; Supplemental Symbols and Pictographs +20000..2A6DF; CJK Unified Ideographs Extension B +2A700..2B73F; CJK Unified Ideographs Extension C +2B740..2B81F; CJK Unified Ideographs Extension D +2B820..2CEAF; CJK Unified Ideographs Extension E +2F800..2FA1F; CJK Compatibility Ideographs Supplement +E0000..E007F; Tags +E0100..E01EF; Variation Selectors Supplement +F0000..FFFFF; Supplementary Private Use Area-A +100000..10FFFF; Supplementary Private Use Area-B + +# EOF
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/DerivedGeneralCategory.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/DerivedGeneralCategory.txt new file mode 100644 index 0000000..96dfb56 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/DerivedGeneralCategory.txt
@@ -0,0 +1,3878 @@ +# DerivedGeneralCategory-9.0.0.txt +# Date: 2016-06-01, 10:34:26 GMT +# © 2016 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ + +# ================================================ + +# Property: General_Category + +# ================================================ + +# General_Category=Unassigned + +0378..0379 ; Cn # [2] <reserved-0378>..<reserved-0379> +0380..0383 ; Cn # [4] <reserved-0380>..<reserved-0383> +038B ; Cn # <reserved-038B> +038D ; Cn # <reserved-038D> +03A2 ; Cn # <reserved-03A2> +0530 ; Cn # <reserved-0530> +0557..0558 ; Cn # [2] <reserved-0557>..<reserved-0558> +0560 ; Cn # <reserved-0560> +0588 ; Cn # <reserved-0588> +058B..058C ; Cn # [2] <reserved-058B>..<reserved-058C> +0590 ; Cn # <reserved-0590> +05C8..05CF ; Cn # [8] <reserved-05C8>..<reserved-05CF> +05EB..05EF ; Cn # [5] <reserved-05EB>..<reserved-05EF> +05F5..05FF ; Cn # [11] <reserved-05F5>..<reserved-05FF> +061D ; Cn # <reserved-061D> +070E ; Cn # <reserved-070E> +074B..074C ; Cn # [2] <reserved-074B>..<reserved-074C> +07B2..07BF ; Cn # [14] <reserved-07B2>..<reserved-07BF> +07FB..07FF ; Cn # [5] <reserved-07FB>..<reserved-07FF> +082E..082F ; Cn # [2] <reserved-082E>..<reserved-082F> +083F ; Cn # <reserved-083F> +085C..085D ; Cn # [2] <reserved-085C>..<reserved-085D> +085F..089F ; Cn # [65] <reserved-085F>..<reserved-089F> +08B5 ; Cn # <reserved-08B5> +08BE..08D3 ; Cn # [22] <reserved-08BE>..<reserved-08D3> +0984 ; Cn # <reserved-0984> +098D..098E ; Cn # [2] <reserved-098D>..<reserved-098E> +0991..0992 ; Cn # [2] <reserved-0991>..<reserved-0992> +09A9 ; Cn # <reserved-09A9> +09B1 ; Cn # <reserved-09B1> +09B3..09B5 ; Cn # [3] <reserved-09B3>..<reserved-09B5> +09BA..09BB ; Cn # [2] <reserved-09BA>..<reserved-09BB> +09C5..09C6 ; Cn # [2] <reserved-09C5>..<reserved-09C6> +09C9..09CA ; Cn # [2] <reserved-09C9>..<reserved-09CA> +09CF..09D6 ; Cn # [8] <reserved-09CF>..<reserved-09D6> +09D8..09DB ; Cn # [4] <reserved-09D8>..<reserved-09DB> +09DE ; Cn # <reserved-09DE> +09E4..09E5 ; Cn # [2] <reserved-09E4>..<reserved-09E5> +09FC..0A00 ; Cn # [5] <reserved-09FC>..<reserved-0A00> +0A04 ; Cn # <reserved-0A04> +0A0B..0A0E ; Cn # [4] <reserved-0A0B>..<reserved-0A0E> +0A11..0A12 ; Cn # [2] <reserved-0A11>..<reserved-0A12> +0A29 ; Cn # <reserved-0A29> +0A31 ; Cn # <reserved-0A31> +0A34 ; Cn # <reserved-0A34> +0A37 ; Cn # <reserved-0A37> +0A3A..0A3B ; Cn # [2] <reserved-0A3A>..<reserved-0A3B> +0A3D ; Cn # <reserved-0A3D> +0A43..0A46 ; Cn # [4] <reserved-0A43>..<reserved-0A46> +0A49..0A4A ; Cn # [2] <reserved-0A49>..<reserved-0A4A> +0A4E..0A50 ; Cn # [3] <reserved-0A4E>..<reserved-0A50> +0A52..0A58 ; Cn # [7] <reserved-0A52>..<reserved-0A58> +0A5D ; Cn # <reserved-0A5D> +0A5F..0A65 ; Cn # [7] <reserved-0A5F>..<reserved-0A65> +0A76..0A80 ; Cn # [11] <reserved-0A76>..<reserved-0A80> +0A84 ; Cn # <reserved-0A84> +0A8E ; Cn # <reserved-0A8E> +0A92 ; Cn # <reserved-0A92> +0AA9 ; Cn # <reserved-0AA9> +0AB1 ; Cn # <reserved-0AB1> +0AB4 ; Cn # <reserved-0AB4> +0ABA..0ABB ; Cn # [2] <reserved-0ABA>..<reserved-0ABB> +0AC6 ; Cn # <reserved-0AC6> +0ACA ; Cn # <reserved-0ACA> +0ACE..0ACF ; Cn # [2] <reserved-0ACE>..<reserved-0ACF> +0AD1..0ADF ; Cn # [15] <reserved-0AD1>..<reserved-0ADF> +0AE4..0AE5 ; Cn # [2] <reserved-0AE4>..<reserved-0AE5> +0AF2..0AF8 ; Cn # [7] <reserved-0AF2>..<reserved-0AF8> +0AFA..0B00 ; Cn # [7] <reserved-0AFA>..<reserved-0B00> +0B04 ; Cn # <reserved-0B04> +0B0D..0B0E ; Cn # [2] <reserved-0B0D>..<reserved-0B0E> +0B11..0B12 ; Cn # [2] <reserved-0B11>..<reserved-0B12> +0B29 ; Cn # <reserved-0B29> +0B31 ; Cn # <reserved-0B31> +0B34 ; Cn # <reserved-0B34> +0B3A..0B3B ; Cn # [2] <reserved-0B3A>..<reserved-0B3B> +0B45..0B46 ; Cn # [2] <reserved-0B45>..<reserved-0B46> +0B49..0B4A ; Cn # [2] <reserved-0B49>..<reserved-0B4A> +0B4E..0B55 ; Cn # [8] <reserved-0B4E>..<reserved-0B55> +0B58..0B5B ; Cn # [4] <reserved-0B58>..<reserved-0B5B> +0B5E ; Cn # <reserved-0B5E> +0B64..0B65 ; Cn # [2] <reserved-0B64>..<reserved-0B65> +0B78..0B81 ; Cn # [10] <reserved-0B78>..<reserved-0B81> +0B84 ; Cn # <reserved-0B84> +0B8B..0B8D ; Cn # [3] <reserved-0B8B>..<reserved-0B8D> +0B91 ; Cn # <reserved-0B91> +0B96..0B98 ; Cn # [3] <reserved-0B96>..<reserved-0B98> +0B9B ; Cn # <reserved-0B9B> +0B9D ; Cn # <reserved-0B9D> +0BA0..0BA2 ; Cn # [3] <reserved-0BA0>..<reserved-0BA2> +0BA5..0BA7 ; Cn # [3] <reserved-0BA5>..<reserved-0BA7> +0BAB..0BAD ; Cn # [3] <reserved-0BAB>..<reserved-0BAD> +0BBA..0BBD ; Cn # [4] <reserved-0BBA>..<reserved-0BBD> +0BC3..0BC5 ; Cn # [3] <reserved-0BC3>..<reserved-0BC5> +0BC9 ; Cn # <reserved-0BC9> +0BCE..0BCF ; Cn # [2] <reserved-0BCE>..<reserved-0BCF> +0BD1..0BD6 ; Cn # [6] <reserved-0BD1>..<reserved-0BD6> +0BD8..0BE5 ; Cn # [14] <reserved-0BD8>..<reserved-0BE5> +0BFB..0BFF ; Cn # [5] <reserved-0BFB>..<reserved-0BFF> +0C04 ; Cn # <reserved-0C04> +0C0D ; Cn # <reserved-0C0D> +0C11 ; Cn # <reserved-0C11> +0C29 ; Cn # <reserved-0C29> +0C3A..0C3C ; Cn # [3] <reserved-0C3A>..<reserved-0C3C> +0C45 ; Cn # <reserved-0C45> +0C49 ; Cn # <reserved-0C49> +0C4E..0C54 ; Cn # [7] <reserved-0C4E>..<reserved-0C54> +0C57 ; Cn # <reserved-0C57> +0C5B..0C5F ; Cn # [5] <reserved-0C5B>..<reserved-0C5F> +0C64..0C65 ; Cn # [2] <reserved-0C64>..<reserved-0C65> +0C70..0C77 ; Cn # [8] <reserved-0C70>..<reserved-0C77> +0C84 ; Cn # <reserved-0C84> +0C8D ; Cn # <reserved-0C8D> +0C91 ; Cn # <reserved-0C91> +0CA9 ; Cn # <reserved-0CA9> +0CB4 ; Cn # <reserved-0CB4> +0CBA..0CBB ; Cn # [2] <reserved-0CBA>..<reserved-0CBB> +0CC5 ; Cn # <reserved-0CC5> +0CC9 ; Cn # <reserved-0CC9> +0CCE..0CD4 ; Cn # [7] <reserved-0CCE>..<reserved-0CD4> +0CD7..0CDD ; Cn # [7] <reserved-0CD7>..<reserved-0CDD> +0CDF ; Cn # <reserved-0CDF> +0CE4..0CE5 ; Cn # [2] <reserved-0CE4>..<reserved-0CE5> +0CF0 ; Cn # <reserved-0CF0> +0CF3..0D00 ; Cn # [14] <reserved-0CF3>..<reserved-0D00> +0D04 ; Cn # <reserved-0D04> +0D0D ; Cn # <reserved-0D0D> +0D11 ; Cn # <reserved-0D11> +0D3B..0D3C ; Cn # [2] <reserved-0D3B>..<reserved-0D3C> +0D45 ; Cn # <reserved-0D45> +0D49 ; Cn # <reserved-0D49> +0D50..0D53 ; Cn # [4] <reserved-0D50>..<reserved-0D53> +0D64..0D65 ; Cn # [2] <reserved-0D64>..<reserved-0D65> +0D80..0D81 ; Cn # [2] <reserved-0D80>..<reserved-0D81> +0D84 ; Cn # <reserved-0D84> +0D97..0D99 ; Cn # [3] <reserved-0D97>..<reserved-0D99> +0DB2 ; Cn # <reserved-0DB2> +0DBC ; Cn # <reserved-0DBC> +0DBE..0DBF ; Cn # [2] <reserved-0DBE>..<reserved-0DBF> +0DC7..0DC9 ; Cn # [3] <reserved-0DC7>..<reserved-0DC9> +0DCB..0DCE ; Cn # [4] <reserved-0DCB>..<reserved-0DCE> +0DD5 ; Cn # <reserved-0DD5> +0DD7 ; Cn # <reserved-0DD7> +0DE0..0DE5 ; Cn # [6] <reserved-0DE0>..<reserved-0DE5> +0DF0..0DF1 ; Cn # [2] <reserved-0DF0>..<reserved-0DF1> +0DF5..0E00 ; Cn # [12] <reserved-0DF5>..<reserved-0E00> +0E3B..0E3E ; Cn # [4] <reserved-0E3B>..<reserved-0E3E> +0E5C..0E80 ; Cn # [37] <reserved-0E5C>..<reserved-0E80> +0E83 ; Cn # <reserved-0E83> +0E85..0E86 ; Cn # [2] <reserved-0E85>..<reserved-0E86> +0E89 ; Cn # <reserved-0E89> +0E8B..0E8C ; Cn # [2] <reserved-0E8B>..<reserved-0E8C> +0E8E..0E93 ; Cn # [6] <reserved-0E8E>..<reserved-0E93> +0E98 ; Cn # <reserved-0E98> +0EA0 ; Cn # <reserved-0EA0> +0EA4 ; Cn # <reserved-0EA4> +0EA6 ; Cn # <reserved-0EA6> +0EA8..0EA9 ; Cn # [2] <reserved-0EA8>..<reserved-0EA9> +0EAC ; Cn # <reserved-0EAC> +0EBA ; Cn # <reserved-0EBA> +0EBE..0EBF ; Cn # [2] <reserved-0EBE>..<reserved-0EBF> +0EC5 ; Cn # <reserved-0EC5> +0EC7 ; Cn # <reserved-0EC7> +0ECE..0ECF ; Cn # [2] <reserved-0ECE>..<reserved-0ECF> +0EDA..0EDB ; Cn # [2] <reserved-0EDA>..<reserved-0EDB> +0EE0..0EFF ; Cn # [32] <reserved-0EE0>..<reserved-0EFF> +0F48 ; Cn # <reserved-0F48> +0F6D..0F70 ; Cn # [4] <reserved-0F6D>..<reserved-0F70> +0F98 ; Cn # <reserved-0F98> +0FBD ; Cn # <reserved-0FBD> +0FCD ; Cn # <reserved-0FCD> +0FDB..0FFF ; Cn # [37] <reserved-0FDB>..<reserved-0FFF> +10C6 ; Cn # <reserved-10C6> +10C8..10CC ; Cn # [5] <reserved-10C8>..<reserved-10CC> +10CE..10CF ; Cn # [2] <reserved-10CE>..<reserved-10CF> +1249 ; Cn # <reserved-1249> +124E..124F ; Cn # [2] <reserved-124E>..<reserved-124F> +1257 ; Cn # <reserved-1257> +1259 ; Cn # <reserved-1259> +125E..125F ; Cn # [2] <reserved-125E>..<reserved-125F> +1289 ; Cn # <reserved-1289> +128E..128F ; Cn # [2] <reserved-128E>..<reserved-128F> +12B1 ; Cn # <reserved-12B1> +12B6..12B7 ; Cn # [2] <reserved-12B6>..<reserved-12B7> +12BF ; Cn # <reserved-12BF> +12C1 ; Cn # <reserved-12C1> +12C6..12C7 ; Cn # [2] <reserved-12C6>..<reserved-12C7> +12D7 ; Cn # <reserved-12D7> +1311 ; Cn # <reserved-1311> +1316..1317 ; Cn # [2] <reserved-1316>..<reserved-1317> +135B..135C ; Cn # [2] <reserved-135B>..<reserved-135C> +137D..137F ; Cn # [3] <reserved-137D>..<reserved-137F> +139A..139F ; Cn # [6] <reserved-139A>..<reserved-139F> +13F6..13F7 ; Cn # [2] <reserved-13F6>..<reserved-13F7> +13FE..13FF ; Cn # [2] <reserved-13FE>..<reserved-13FF> +169D..169F ; Cn # [3] <reserved-169D>..<reserved-169F> +16F9..16FF ; Cn # [7] <reserved-16F9>..<reserved-16FF> +170D ; Cn # <reserved-170D> +1715..171F ; Cn # [11] <reserved-1715>..<reserved-171F> +1737..173F ; Cn # [9] <reserved-1737>..<reserved-173F> +1754..175F ; Cn # [12] <reserved-1754>..<reserved-175F> +176D ; Cn # <reserved-176D> +1771 ; Cn # <reserved-1771> +1774..177F ; Cn # [12] <reserved-1774>..<reserved-177F> +17DE..17DF ; Cn # [2] <reserved-17DE>..<reserved-17DF> +17EA..17EF ; Cn # [6] <reserved-17EA>..<reserved-17EF> +17FA..17FF ; Cn # [6] <reserved-17FA>..<reserved-17FF> +180F ; Cn # <reserved-180F> +181A..181F ; Cn # [6] <reserved-181A>..<reserved-181F> +1878..187F ; Cn # [8] <reserved-1878>..<reserved-187F> +18AB..18AF ; Cn # [5] <reserved-18AB>..<reserved-18AF> +18F6..18FF ; Cn # [10] <reserved-18F6>..<reserved-18FF> +191F ; Cn # <reserved-191F> +192C..192F ; Cn # [4] <reserved-192C>..<reserved-192F> +193C..193F ; Cn # [4] <reserved-193C>..<reserved-193F> +1941..1943 ; Cn # [3] <reserved-1941>..<reserved-1943> +196E..196F ; Cn # [2] <reserved-196E>..<reserved-196F> +1975..197F ; Cn # [11] <reserved-1975>..<reserved-197F> +19AC..19AF ; Cn # [4] <reserved-19AC>..<reserved-19AF> +19CA..19CF ; Cn # [6] <reserved-19CA>..<reserved-19CF> +19DB..19DD ; Cn # [3] <reserved-19DB>..<reserved-19DD> +1A1C..1A1D ; Cn # [2] <reserved-1A1C>..<reserved-1A1D> +1A5F ; Cn # <reserved-1A5F> +1A7D..1A7E ; Cn # [2] <reserved-1A7D>..<reserved-1A7E> +1A8A..1A8F ; Cn # [6] <reserved-1A8A>..<reserved-1A8F> +1A9A..1A9F ; Cn # [6] <reserved-1A9A>..<reserved-1A9F> +1AAE..1AAF ; Cn # [2] <reserved-1AAE>..<reserved-1AAF> +1ABF..1AFF ; Cn # [65] <reserved-1ABF>..<reserved-1AFF> +1B4C..1B4F ; Cn # [4] <reserved-1B4C>..<reserved-1B4F> +1B7D..1B7F ; Cn # [3] <reserved-1B7D>..<reserved-1B7F> +1BF4..1BFB ; Cn # [8] <reserved-1BF4>..<reserved-1BFB> +1C38..1C3A ; Cn # [3] <reserved-1C38>..<reserved-1C3A> +1C4A..1C4C ; Cn # [3] <reserved-1C4A>..<reserved-1C4C> +1C89..1CBF ; Cn # [55] <reserved-1C89>..<reserved-1CBF> +1CC8..1CCF ; Cn # [8] <reserved-1CC8>..<reserved-1CCF> +1CF7 ; Cn # <reserved-1CF7> +1CFA..1CFF ; Cn # [6] <reserved-1CFA>..<reserved-1CFF> +1DF6..1DFA ; Cn # [5] <reserved-1DF6>..<reserved-1DFA> +1F16..1F17 ; Cn # [2] <reserved-1F16>..<reserved-1F17> +1F1E..1F1F ; Cn # [2] <reserved-1F1E>..<reserved-1F1F> +1F46..1F47 ; Cn # [2] <reserved-1F46>..<reserved-1F47> +1F4E..1F4F ; Cn # [2] <reserved-1F4E>..<reserved-1F4F> +1F58 ; Cn # <reserved-1F58> +1F5A ; Cn # <reserved-1F5A> +1F5C ; Cn # <reserved-1F5C> +1F5E ; Cn # <reserved-1F5E> +1F7E..1F7F ; Cn # [2] <reserved-1F7E>..<reserved-1F7F> +1FB5 ; Cn # <reserved-1FB5> +1FC5 ; Cn # <reserved-1FC5> +1FD4..1FD5 ; Cn # [2] <reserved-1FD4>..<reserved-1FD5> +1FDC ; Cn # <reserved-1FDC> +1FF0..1FF1 ; Cn # [2] <reserved-1FF0>..<reserved-1FF1> +1FF5 ; Cn # <reserved-1FF5> +1FFF ; Cn # <reserved-1FFF> +2065 ; Cn # <reserved-2065> +2072..2073 ; Cn # [2] <reserved-2072>..<reserved-2073> +208F ; Cn # <reserved-208F> +209D..209F ; Cn # [3] <reserved-209D>..<reserved-209F> +20BF..20CF ; Cn # [17] <reserved-20BF>..<reserved-20CF> +20F1..20FF ; Cn # [15] <reserved-20F1>..<reserved-20FF> +218C..218F ; Cn # [4] <reserved-218C>..<reserved-218F> +23FF ; Cn # <reserved-23FF> +2427..243F ; Cn # [25] <reserved-2427>..<reserved-243F> +244B..245F ; Cn # [21] <reserved-244B>..<reserved-245F> +2B74..2B75 ; Cn # [2] <reserved-2B74>..<reserved-2B75> +2B96..2B97 ; Cn # [2] <reserved-2B96>..<reserved-2B97> +2BBA..2BBC ; Cn # [3] <reserved-2BBA>..<reserved-2BBC> +2BC9 ; Cn # <reserved-2BC9> +2BD2..2BEB ; Cn # [26] <reserved-2BD2>..<reserved-2BEB> +2BF0..2BFF ; Cn # [16] <reserved-2BF0>..<reserved-2BFF> +2C2F ; Cn # <reserved-2C2F> +2C5F ; Cn # <reserved-2C5F> +2CF4..2CF8 ; Cn # [5] <reserved-2CF4>..<reserved-2CF8> +2D26 ; Cn # <reserved-2D26> +2D28..2D2C ; Cn # [5] <reserved-2D28>..<reserved-2D2C> +2D2E..2D2F ; Cn # [2] <reserved-2D2E>..<reserved-2D2F> +2D68..2D6E ; Cn # [7] <reserved-2D68>..<reserved-2D6E> +2D71..2D7E ; Cn # [14] <reserved-2D71>..<reserved-2D7E> +2D97..2D9F ; Cn # [9] <reserved-2D97>..<reserved-2D9F> +2DA7 ; Cn # <reserved-2DA7> +2DAF ; Cn # <reserved-2DAF> +2DB7 ; Cn # <reserved-2DB7> +2DBF ; Cn # <reserved-2DBF> +2DC7 ; Cn # <reserved-2DC7> +2DCF ; Cn # <reserved-2DCF> +2DD7 ; Cn # <reserved-2DD7> +2DDF ; Cn # <reserved-2DDF> +2E45..2E7F ; Cn # [59] <reserved-2E45>..<reserved-2E7F> +2E9A ; Cn # <reserved-2E9A> +2EF4..2EFF ; Cn # [12] <reserved-2EF4>..<reserved-2EFF> +2FD6..2FEF ; Cn # [26] <reserved-2FD6>..<reserved-2FEF> +2FFC..2FFF ; Cn # [4] <reserved-2FFC>..<reserved-2FFF> +3040 ; Cn # <reserved-3040> +3097..3098 ; Cn # [2] <reserved-3097>..<reserved-3098> +3100..3104 ; Cn # [5] <reserved-3100>..<reserved-3104> +312E..3130 ; Cn # [3] <reserved-312E>..<reserved-3130> +318F ; Cn # <reserved-318F> +31BB..31BF ; Cn # [5] <reserved-31BB>..<reserved-31BF> +31E4..31EF ; Cn # [12] <reserved-31E4>..<reserved-31EF> +321F ; Cn # <reserved-321F> +32FF ; Cn # <reserved-32FF> +4DB6..4DBF ; Cn # [10] <reserved-4DB6>..<reserved-4DBF> +9FD6..9FFF ; Cn # [42] <reserved-9FD6>..<reserved-9FFF> +A48D..A48F ; Cn # [3] <reserved-A48D>..<reserved-A48F> +A4C7..A4CF ; Cn # [9] <reserved-A4C7>..<reserved-A4CF> +A62C..A63F ; Cn # [20] <reserved-A62C>..<reserved-A63F> +A6F8..A6FF ; Cn # [8] <reserved-A6F8>..<reserved-A6FF> +A7AF ; Cn # <reserved-A7AF> +A7B8..A7F6 ; Cn # [63] <reserved-A7B8>..<reserved-A7F6> +A82C..A82F ; Cn # [4] <reserved-A82C>..<reserved-A82F> +A83A..A83F ; Cn # [6] <reserved-A83A>..<reserved-A83F> +A878..A87F ; Cn # [8] <reserved-A878>..<reserved-A87F> +A8C6..A8CD ; Cn # [8] <reserved-A8C6>..<reserved-A8CD> +A8DA..A8DF ; Cn # [6] <reserved-A8DA>..<reserved-A8DF> +A8FE..A8FF ; Cn # [2] <reserved-A8FE>..<reserved-A8FF> +A954..A95E ; Cn # [11] <reserved-A954>..<reserved-A95E> +A97D..A97F ; Cn # [3] <reserved-A97D>..<reserved-A97F> +A9CE ; Cn # <reserved-A9CE> +A9DA..A9DD ; Cn # [4] <reserved-A9DA>..<reserved-A9DD> +A9FF ; Cn # <reserved-A9FF> +AA37..AA3F ; Cn # [9] <reserved-AA37>..<reserved-AA3F> +AA4E..AA4F ; Cn # [2] <reserved-AA4E>..<reserved-AA4F> +AA5A..AA5B ; Cn # [2] <reserved-AA5A>..<reserved-AA5B> +AAC3..AADA ; Cn # [24] <reserved-AAC3>..<reserved-AADA> +AAF7..AB00 ; Cn # [10] <reserved-AAF7>..<reserved-AB00> +AB07..AB08 ; Cn # [2] <reserved-AB07>..<reserved-AB08> +AB0F..AB10 ; Cn # [2] <reserved-AB0F>..<reserved-AB10> +AB17..AB1F ; Cn # [9] <reserved-AB17>..<reserved-AB1F> +AB27 ; Cn # <reserved-AB27> +AB2F ; Cn # <reserved-AB2F> +AB66..AB6F ; Cn # [10] <reserved-AB66>..<reserved-AB6F> +ABEE..ABEF ; Cn # [2] <reserved-ABEE>..<reserved-ABEF> +ABFA..ABFF ; Cn # [6] <reserved-ABFA>..<reserved-ABFF> +D7A4..D7AF ; Cn # [12] <reserved-D7A4>..<reserved-D7AF> +D7C7..D7CA ; Cn # [4] <reserved-D7C7>..<reserved-D7CA> +D7FC..D7FF ; Cn # [4] <reserved-D7FC>..<reserved-D7FF> +FA6E..FA6F ; Cn # [2] <reserved-FA6E>..<reserved-FA6F> +FADA..FAFF ; Cn # [38] <reserved-FADA>..<reserved-FAFF> +FB07..FB12 ; Cn # [12] <reserved-FB07>..<reserved-FB12> +FB18..FB1C ; Cn # [5] <reserved-FB18>..<reserved-FB1C> +FB37 ; Cn # <reserved-FB37> +FB3D ; Cn # <reserved-FB3D> +FB3F ; Cn # <reserved-FB3F> +FB42 ; Cn # <reserved-FB42> +FB45 ; Cn # <reserved-FB45> +FBC2..FBD2 ; Cn # [17] <reserved-FBC2>..<reserved-FBD2> +FD40..FD4F ; Cn # [16] <reserved-FD40>..<reserved-FD4F> +FD90..FD91 ; Cn # [2] <reserved-FD90>..<reserved-FD91> +FDC8..FDEF ; Cn # [40] <reserved-FDC8>..<noncharacter-FDEF> +FDFE..FDFF ; Cn # [2] <reserved-FDFE>..<reserved-FDFF> +FE1A..FE1F ; Cn # [6] <reserved-FE1A>..<reserved-FE1F> +FE53 ; Cn # <reserved-FE53> +FE67 ; Cn # <reserved-FE67> +FE6C..FE6F ; Cn # [4] <reserved-FE6C>..<reserved-FE6F> +FE75 ; Cn # <reserved-FE75> +FEFD..FEFE ; Cn # [2] <reserved-FEFD>..<reserved-FEFE> +FF00 ; Cn # <reserved-FF00> +FFBF..FFC1 ; Cn # [3] <reserved-FFBF>..<reserved-FFC1> +FFC8..FFC9 ; Cn # [2] <reserved-FFC8>..<reserved-FFC9> +FFD0..FFD1 ; Cn # [2] <reserved-FFD0>..<reserved-FFD1> +FFD8..FFD9 ; Cn # [2] <reserved-FFD8>..<reserved-FFD9> +FFDD..FFDF ; Cn # [3] <reserved-FFDD>..<reserved-FFDF> +FFE7 ; Cn # <reserved-FFE7> +FFEF..FFF8 ; Cn # [10] <reserved-FFEF>..<reserved-FFF8> +FFFE..FFFF ; Cn # [2] <noncharacter-FFFE>..<noncharacter-FFFF> +1000C ; Cn # <reserved-1000C> +10027 ; Cn # <reserved-10027> +1003B ; Cn # <reserved-1003B> +1003E ; Cn # <reserved-1003E> +1004E..1004F ; Cn # [2] <reserved-1004E>..<reserved-1004F> +1005E..1007F ; Cn # [34] <reserved-1005E>..<reserved-1007F> +100FB..100FF ; Cn # [5] <reserved-100FB>..<reserved-100FF> +10103..10106 ; Cn # [4] <reserved-10103>..<reserved-10106> +10134..10136 ; Cn # [3] <reserved-10134>..<reserved-10136> +1018F ; Cn # <reserved-1018F> +1019C..1019F ; Cn # [4] <reserved-1019C>..<reserved-1019F> +101A1..101CF ; Cn # [47] <reserved-101A1>..<reserved-101CF> +101FE..1027F ; Cn # [130] <reserved-101FE>..<reserved-1027F> +1029D..1029F ; Cn # [3] <reserved-1029D>..<reserved-1029F> +102D1..102DF ; Cn # [15] <reserved-102D1>..<reserved-102DF> +102FC..102FF ; Cn # [4] <reserved-102FC>..<reserved-102FF> +10324..1032F ; Cn # [12] <reserved-10324>..<reserved-1032F> +1034B..1034F ; Cn # [5] <reserved-1034B>..<reserved-1034F> +1037B..1037F ; Cn # [5] <reserved-1037B>..<reserved-1037F> +1039E ; Cn # <reserved-1039E> +103C4..103C7 ; Cn # [4] <reserved-103C4>..<reserved-103C7> +103D6..103FF ; Cn # [42] <reserved-103D6>..<reserved-103FF> +1049E..1049F ; Cn # [2] <reserved-1049E>..<reserved-1049F> +104AA..104AF ; Cn # [6] <reserved-104AA>..<reserved-104AF> +104D4..104D7 ; Cn # [4] <reserved-104D4>..<reserved-104D7> +104FC..104FF ; Cn # [4] <reserved-104FC>..<reserved-104FF> +10528..1052F ; Cn # [8] <reserved-10528>..<reserved-1052F> +10564..1056E ; Cn # [11] <reserved-10564>..<reserved-1056E> +10570..105FF ; Cn # [144] <reserved-10570>..<reserved-105FF> +10737..1073F ; Cn # [9] <reserved-10737>..<reserved-1073F> +10756..1075F ; Cn # [10] <reserved-10756>..<reserved-1075F> +10768..107FF ; Cn # [152] <reserved-10768>..<reserved-107FF> +10806..10807 ; Cn # [2] <reserved-10806>..<reserved-10807> +10809 ; Cn # <reserved-10809> +10836 ; Cn # <reserved-10836> +10839..1083B ; Cn # [3] <reserved-10839>..<reserved-1083B> +1083D..1083E ; Cn # [2] <reserved-1083D>..<reserved-1083E> +10856 ; Cn # <reserved-10856> +1089F..108A6 ; Cn # [8] <reserved-1089F>..<reserved-108A6> +108B0..108DF ; Cn # [48] <reserved-108B0>..<reserved-108DF> +108F3 ; Cn # <reserved-108F3> +108F6..108FA ; Cn # [5] <reserved-108F6>..<reserved-108FA> +1091C..1091E ; Cn # [3] <reserved-1091C>..<reserved-1091E> +1093A..1093E ; Cn # [5] <reserved-1093A>..<reserved-1093E> +10940..1097F ; Cn # [64] <reserved-10940>..<reserved-1097F> +109B8..109BB ; Cn # [4] <reserved-109B8>..<reserved-109BB> +109D0..109D1 ; Cn # [2] <reserved-109D0>..<reserved-109D1> +10A04 ; Cn # <reserved-10A04> +10A07..10A0B ; Cn # [5] <reserved-10A07>..<reserved-10A0B> +10A14 ; Cn # <reserved-10A14> +10A18 ; Cn # <reserved-10A18> +10A34..10A37 ; Cn # [4] <reserved-10A34>..<reserved-10A37> +10A3B..10A3E ; Cn # [4] <reserved-10A3B>..<reserved-10A3E> +10A48..10A4F ; Cn # [8] <reserved-10A48>..<reserved-10A4F> +10A59..10A5F ; Cn # [7] <reserved-10A59>..<reserved-10A5F> +10AA0..10ABF ; Cn # [32] <reserved-10AA0>..<reserved-10ABF> +10AE7..10AEA ; Cn # [4] <reserved-10AE7>..<reserved-10AEA> +10AF7..10AFF ; Cn # [9] <reserved-10AF7>..<reserved-10AFF> +10B36..10B38 ; Cn # [3] <reserved-10B36>..<reserved-10B38> +10B56..10B57 ; Cn # [2] <reserved-10B56>..<reserved-10B57> +10B73..10B77 ; Cn # [5] <reserved-10B73>..<reserved-10B77> +10B92..10B98 ; Cn # [7] <reserved-10B92>..<reserved-10B98> +10B9D..10BA8 ; Cn # [12] <reserved-10B9D>..<reserved-10BA8> +10BB0..10BFF ; Cn # [80] <reserved-10BB0>..<reserved-10BFF> +10C49..10C7F ; Cn # [55] <reserved-10C49>..<reserved-10C7F> +10CB3..10CBF ; Cn # [13] <reserved-10CB3>..<reserved-10CBF> +10CF3..10CF9 ; Cn # [7] <reserved-10CF3>..<reserved-10CF9> +10D00..10E5F ; Cn # [352] <reserved-10D00>..<reserved-10E5F> +10E7F..10FFF ; Cn # [385] <reserved-10E7F>..<reserved-10FFF> +1104E..11051 ; Cn # [4] <reserved-1104E>..<reserved-11051> +11070..1107E ; Cn # [15] <reserved-11070>..<reserved-1107E> +110C2..110CF ; Cn # [14] <reserved-110C2>..<reserved-110CF> +110E9..110EF ; Cn # [7] <reserved-110E9>..<reserved-110EF> +110FA..110FF ; Cn # [6] <reserved-110FA>..<reserved-110FF> +11135 ; Cn # <reserved-11135> +11144..1114F ; Cn # [12] <reserved-11144>..<reserved-1114F> +11177..1117F ; Cn # [9] <reserved-11177>..<reserved-1117F> +111CE..111CF ; Cn # [2] <reserved-111CE>..<reserved-111CF> +111E0 ; Cn # <reserved-111E0> +111F5..111FF ; Cn # [11] <reserved-111F5>..<reserved-111FF> +11212 ; Cn # <reserved-11212> +1123F..1127F ; Cn # [65] <reserved-1123F>..<reserved-1127F> +11287 ; Cn # <reserved-11287> +11289 ; Cn # <reserved-11289> +1128E ; Cn # <reserved-1128E> +1129E ; Cn # <reserved-1129E> +112AA..112AF ; Cn # [6] <reserved-112AA>..<reserved-112AF> +112EB..112EF ; Cn # [5] <reserved-112EB>..<reserved-112EF> +112FA..112FF ; Cn # [6] <reserved-112FA>..<reserved-112FF> +11304 ; Cn # <reserved-11304> +1130D..1130E ; Cn # [2] <reserved-1130D>..<reserved-1130E> +11311..11312 ; Cn # [2] <reserved-11311>..<reserved-11312> +11329 ; Cn # <reserved-11329> +11331 ; Cn # <reserved-11331> +11334 ; Cn # <reserved-11334> +1133A..1133B ; Cn # [2] <reserved-1133A>..<reserved-1133B> +11345..11346 ; Cn # [2] <reserved-11345>..<reserved-11346> +11349..1134A ; Cn # [2] <reserved-11349>..<reserved-1134A> +1134E..1134F ; Cn # [2] <reserved-1134E>..<reserved-1134F> +11351..11356 ; Cn # [6] <reserved-11351>..<reserved-11356> +11358..1135C ; Cn # [5] <reserved-11358>..<reserved-1135C> +11364..11365 ; Cn # [2] <reserved-11364>..<reserved-11365> +1136D..1136F ; Cn # [3] <reserved-1136D>..<reserved-1136F> +11375..113FF ; Cn # [139] <reserved-11375>..<reserved-113FF> +1145A ; Cn # <reserved-1145A> +1145C ; Cn # <reserved-1145C> +1145E..1147F ; Cn # [34] <reserved-1145E>..<reserved-1147F> +114C8..114CF ; Cn # [8] <reserved-114C8>..<reserved-114CF> +114DA..1157F ; Cn # [166] <reserved-114DA>..<reserved-1157F> +115B6..115B7 ; Cn # [2] <reserved-115B6>..<reserved-115B7> +115DE..115FF ; Cn # [34] <reserved-115DE>..<reserved-115FF> +11645..1164F ; Cn # [11] <reserved-11645>..<reserved-1164F> +1165A..1165F ; Cn # [6] <reserved-1165A>..<reserved-1165F> +1166D..1167F ; Cn # [19] <reserved-1166D>..<reserved-1167F> +116B8..116BF ; Cn # [8] <reserved-116B8>..<reserved-116BF> +116CA..116FF ; Cn # [54] <reserved-116CA>..<reserved-116FF> +1171A..1171C ; Cn # [3] <reserved-1171A>..<reserved-1171C> +1172C..1172F ; Cn # [4] <reserved-1172C>..<reserved-1172F> +11740..1189F ; Cn # [352] <reserved-11740>..<reserved-1189F> +118F3..118FE ; Cn # [12] <reserved-118F3>..<reserved-118FE> +11900..11ABF ; Cn # [448] <reserved-11900>..<reserved-11ABF> +11AF9..11BFF ; Cn # [263] <reserved-11AF9>..<reserved-11BFF> +11C09 ; Cn # <reserved-11C09> +11C37 ; Cn # <reserved-11C37> +11C46..11C4F ; Cn # [10] <reserved-11C46>..<reserved-11C4F> +11C6D..11C6F ; Cn # [3] <reserved-11C6D>..<reserved-11C6F> +11C90..11C91 ; Cn # [2] <reserved-11C90>..<reserved-11C91> +11CA8 ; Cn # <reserved-11CA8> +11CB7..11FFF ; Cn # [841] <reserved-11CB7>..<reserved-11FFF> +1239A..123FF ; Cn # [102] <reserved-1239A>..<reserved-123FF> +1246F ; Cn # <reserved-1246F> +12475..1247F ; Cn # [11] <reserved-12475>..<reserved-1247F> +12544..12FFF ; Cn # [2748] <reserved-12544>..<reserved-12FFF> +1342F..143FF ; Cn # [4049] <reserved-1342F>..<reserved-143FF> +14647..167FF ; Cn # [8633] <reserved-14647>..<reserved-167FF> +16A39..16A3F ; Cn # [7] <reserved-16A39>..<reserved-16A3F> +16A5F ; Cn # <reserved-16A5F> +16A6A..16A6D ; Cn # [4] <reserved-16A6A>..<reserved-16A6D> +16A70..16ACF ; Cn # [96] <reserved-16A70>..<reserved-16ACF> +16AEE..16AEF ; Cn # [2] <reserved-16AEE>..<reserved-16AEF> +16AF6..16AFF ; Cn # [10] <reserved-16AF6>..<reserved-16AFF> +16B46..16B4F ; Cn # [10] <reserved-16B46>..<reserved-16B4F> +16B5A ; Cn # <reserved-16B5A> +16B62 ; Cn # <reserved-16B62> +16B78..16B7C ; Cn # [5] <reserved-16B78>..<reserved-16B7C> +16B90..16EFF ; Cn # [880] <reserved-16B90>..<reserved-16EFF> +16F45..16F4F ; Cn # [11] <reserved-16F45>..<reserved-16F4F> +16F7F..16F8E ; Cn # [16] <reserved-16F7F>..<reserved-16F8E> +16FA0..16FDF ; Cn # [64] <reserved-16FA0>..<reserved-16FDF> +16FE1..16FFF ; Cn # [31] <reserved-16FE1>..<reserved-16FFF> +187ED..187FF ; Cn # [19] <reserved-187ED>..<reserved-187FF> +18AF3..1AFFF ; Cn # [9485] <reserved-18AF3>..<reserved-1AFFF> +1B002..1BBFF ; Cn # [3070] <reserved-1B002>..<reserved-1BBFF> +1BC6B..1BC6F ; Cn # [5] <reserved-1BC6B>..<reserved-1BC6F> +1BC7D..1BC7F ; Cn # [3] <reserved-1BC7D>..<reserved-1BC7F> +1BC89..1BC8F ; Cn # [7] <reserved-1BC89>..<reserved-1BC8F> +1BC9A..1BC9B ; Cn # [2] <reserved-1BC9A>..<reserved-1BC9B> +1BCA4..1CFFF ; Cn # [4956] <reserved-1BCA4>..<reserved-1CFFF> +1D0F6..1D0FF ; Cn # [10] <reserved-1D0F6>..<reserved-1D0FF> +1D127..1D128 ; Cn # [2] <reserved-1D127>..<reserved-1D128> +1D1E9..1D1FF ; Cn # [23] <reserved-1D1E9>..<reserved-1D1FF> +1D246..1D2FF ; Cn # [186] <reserved-1D246>..<reserved-1D2FF> +1D357..1D35F ; Cn # [9] <reserved-1D357>..<reserved-1D35F> +1D372..1D3FF ; Cn # [142] <reserved-1D372>..<reserved-1D3FF> +1D455 ; Cn # <reserved-1D455> +1D49D ; Cn # <reserved-1D49D> +1D4A0..1D4A1 ; Cn # [2] <reserved-1D4A0>..<reserved-1D4A1> +1D4A3..1D4A4 ; Cn # [2] <reserved-1D4A3>..<reserved-1D4A4> +1D4A7..1D4A8 ; Cn # [2] <reserved-1D4A7>..<reserved-1D4A8> +1D4AD ; Cn # <reserved-1D4AD> +1D4BA ; Cn # <reserved-1D4BA> +1D4BC ; Cn # <reserved-1D4BC> +1D4C4 ; Cn # <reserved-1D4C4> +1D506 ; Cn # <reserved-1D506> +1D50B..1D50C ; Cn # [2] <reserved-1D50B>..<reserved-1D50C> +1D515 ; Cn # <reserved-1D515> +1D51D ; Cn # <reserved-1D51D> +1D53A ; Cn # <reserved-1D53A> +1D53F ; Cn # <reserved-1D53F> +1D545 ; Cn # <reserved-1D545> +1D547..1D549 ; Cn # [3] <reserved-1D547>..<reserved-1D549> +1D551 ; Cn # <reserved-1D551> +1D6A6..1D6A7 ; Cn # [2] <reserved-1D6A6>..<reserved-1D6A7> +1D7CC..1D7CD ; Cn # [2] <reserved-1D7CC>..<reserved-1D7CD> +1DA8C..1DA9A ; Cn # [15] <reserved-1DA8C>..<reserved-1DA9A> +1DAA0 ; Cn # <reserved-1DAA0> +1DAB0..1DFFF ; Cn # [1360] <reserved-1DAB0>..<reserved-1DFFF> +1E007 ; Cn # <reserved-1E007> +1E019..1E01A ; Cn # [2] <reserved-1E019>..<reserved-1E01A> +1E022 ; Cn # <reserved-1E022> +1E025 ; Cn # <reserved-1E025> +1E02B..1E7FF ; Cn # [2005] <reserved-1E02B>..<reserved-1E7FF> +1E8C5..1E8C6 ; Cn # [2] <reserved-1E8C5>..<reserved-1E8C6> +1E8D7..1E8FF ; Cn # [41] <reserved-1E8D7>..<reserved-1E8FF> +1E94B..1E94F ; Cn # [5] <reserved-1E94B>..<reserved-1E94F> +1E95A..1E95D ; Cn # [4] <reserved-1E95A>..<reserved-1E95D> +1E960..1EDFF ; Cn # [1184] <reserved-1E960>..<reserved-1EDFF> +1EE04 ; Cn # <reserved-1EE04> +1EE20 ; Cn # <reserved-1EE20> +1EE23 ; Cn # <reserved-1EE23> +1EE25..1EE26 ; Cn # [2] <reserved-1EE25>..<reserved-1EE26> +1EE28 ; Cn # <reserved-1EE28> +1EE33 ; Cn # <reserved-1EE33> +1EE38 ; Cn # <reserved-1EE38> +1EE3A ; Cn # <reserved-1EE3A> +1EE3C..1EE41 ; Cn # [6] <reserved-1EE3C>..<reserved-1EE41> +1EE43..1EE46 ; Cn # [4] <reserved-1EE43>..<reserved-1EE46> +1EE48 ; Cn # <reserved-1EE48> +1EE4A ; Cn # <reserved-1EE4A> +1EE4C ; Cn # <reserved-1EE4C> +1EE50 ; Cn # <reserved-1EE50> +1EE53 ; Cn # <reserved-1EE53> +1EE55..1EE56 ; Cn # [2] <reserved-1EE55>..<reserved-1EE56> +1EE58 ; Cn # <reserved-1EE58> +1EE5A ; Cn # <reserved-1EE5A> +1EE5C ; Cn # <reserved-1EE5C> +1EE5E ; Cn # <reserved-1EE5E> +1EE60 ; Cn # <reserved-1EE60> +1EE63 ; Cn # <reserved-1EE63> +1EE65..1EE66 ; Cn # [2] <reserved-1EE65>..<reserved-1EE66> +1EE6B ; Cn # <reserved-1EE6B> +1EE73 ; Cn # <reserved-1EE73> +1EE78 ; Cn # <reserved-1EE78> +1EE7D ; Cn # <reserved-1EE7D> +1EE7F ; Cn # <reserved-1EE7F> +1EE8A ; Cn # <reserved-1EE8A> +1EE9C..1EEA0 ; Cn # [5] <reserved-1EE9C>..<reserved-1EEA0> +1EEA4 ; Cn # <reserved-1EEA4> +1EEAA ; Cn # <reserved-1EEAA> +1EEBC..1EEEF ; Cn # [52] <reserved-1EEBC>..<reserved-1EEEF> +1EEF2..1EFFF ; Cn # [270] <reserved-1EEF2>..<reserved-1EFFF> +1F02C..1F02F ; Cn # [4] <reserved-1F02C>..<reserved-1F02F> +1F094..1F09F ; Cn # [12] <reserved-1F094>..<reserved-1F09F> +1F0AF..1F0B0 ; Cn # [2] <reserved-1F0AF>..<reserved-1F0B0> +1F0C0 ; Cn # <reserved-1F0C0> +1F0D0 ; Cn # <reserved-1F0D0> +1F0F6..1F0FF ; Cn # [10] <reserved-1F0F6>..<reserved-1F0FF> +1F10D..1F10F ; Cn # [3] <reserved-1F10D>..<reserved-1F10F> +1F12F ; Cn # <reserved-1F12F> +1F16C..1F16F ; Cn # [4] <reserved-1F16C>..<reserved-1F16F> +1F1AD..1F1E5 ; Cn # [57] <reserved-1F1AD>..<reserved-1F1E5> +1F203..1F20F ; Cn # [13] <reserved-1F203>..<reserved-1F20F> +1F23C..1F23F ; Cn # [4] <reserved-1F23C>..<reserved-1F23F> +1F249..1F24F ; Cn # [7] <reserved-1F249>..<reserved-1F24F> +1F252..1F2FF ; Cn # [174] <reserved-1F252>..<reserved-1F2FF> +1F6D3..1F6DF ; Cn # [13] <reserved-1F6D3>..<reserved-1F6DF> +1F6ED..1F6EF ; Cn # [3] <reserved-1F6ED>..<reserved-1F6EF> +1F6F7..1F6FF ; Cn # [9] <reserved-1F6F7>..<reserved-1F6FF> +1F774..1F77F ; Cn # [12] <reserved-1F774>..<reserved-1F77F> +1F7D5..1F7FF ; Cn # [43] <reserved-1F7D5>..<reserved-1F7FF> +1F80C..1F80F ; Cn # [4] <reserved-1F80C>..<reserved-1F80F> +1F848..1F84F ; Cn # [8] <reserved-1F848>..<reserved-1F84F> +1F85A..1F85F ; Cn # [6] <reserved-1F85A>..<reserved-1F85F> +1F888..1F88F ; Cn # [8] <reserved-1F888>..<reserved-1F88F> +1F8AE..1F90F ; Cn # [98] <reserved-1F8AE>..<reserved-1F90F> +1F91F ; Cn # <reserved-1F91F> +1F928..1F92F ; Cn # [8] <reserved-1F928>..<reserved-1F92F> +1F931..1F932 ; Cn # [2] <reserved-1F931>..<reserved-1F932> +1F93F ; Cn # <reserved-1F93F> +1F94C..1F94F ; Cn # [4] <reserved-1F94C>..<reserved-1F94F> +1F95F..1F97F ; Cn # [33] <reserved-1F95F>..<reserved-1F97F> +1F992..1F9BF ; Cn # [46] <reserved-1F992>..<reserved-1F9BF> +1F9C1..1FFFF ; Cn # [1599] <reserved-1F9C1>..<noncharacter-1FFFF> +2A6D7..2A6FF ; Cn # [41] <reserved-2A6D7>..<reserved-2A6FF> +2B735..2B73F ; Cn # [11] <reserved-2B735>..<reserved-2B73F> +2B81E..2B81F ; Cn # [2] <reserved-2B81E>..<reserved-2B81F> +2CEA2..2F7FF ; Cn # [10590] <reserved-2CEA2>..<reserved-2F7FF> +2FA1E..E0000 ; Cn # [722403] <reserved-2FA1E>..<reserved-E0000> +E0002..E001F ; Cn # [30] <reserved-E0002>..<reserved-E001F> +E0080..E00FF ; Cn # [128] <reserved-E0080>..<reserved-E00FF> +E01F0..EFFFF ; Cn # [65040] <reserved-E01F0>..<noncharacter-EFFFF> +FFFFE..FFFFF ; Cn # [2] <noncharacter-FFFFE>..<noncharacter-FFFFF> +10FFFE..10FFFF; Cn # [2] <noncharacter-10FFFE>..<noncharacter-10FFFF> + +# Total code points: 846359 + +# ================================================ + +# General_Category=Uppercase_Letter + +0041..005A ; Lu # [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z +00C0..00D6 ; Lu # [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS +00D8..00DE ; Lu # [7] LATIN CAPITAL LETTER O WITH STROKE..LATIN CAPITAL LETTER THORN +0100 ; Lu # LATIN CAPITAL LETTER A WITH MACRON +0102 ; Lu # LATIN CAPITAL LETTER A WITH BREVE +0104 ; Lu # LATIN CAPITAL LETTER A WITH OGONEK +0106 ; Lu # LATIN CAPITAL LETTER C WITH ACUTE +0108 ; Lu # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A ; Lu # LATIN CAPITAL LETTER C WITH DOT ABOVE +010C ; Lu # LATIN CAPITAL LETTER C WITH CARON +010E ; Lu # LATIN CAPITAL LETTER D WITH CARON +0110 ; Lu # LATIN CAPITAL LETTER D WITH STROKE +0112 ; Lu # LATIN CAPITAL LETTER E WITH MACRON +0114 ; Lu # LATIN CAPITAL LETTER E WITH BREVE +0116 ; Lu # LATIN CAPITAL LETTER E WITH DOT ABOVE +0118 ; Lu # LATIN CAPITAL LETTER E WITH OGONEK +011A ; Lu # LATIN CAPITAL LETTER E WITH CARON +011C ; Lu # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011E ; Lu # LATIN CAPITAL LETTER G WITH BREVE +0120 ; Lu # LATIN CAPITAL LETTER G WITH DOT ABOVE +0122 ; Lu # LATIN CAPITAL LETTER G WITH CEDILLA +0124 ; Lu # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0126 ; Lu # LATIN CAPITAL LETTER H WITH STROKE +0128 ; Lu # LATIN CAPITAL LETTER I WITH TILDE +012A ; Lu # LATIN CAPITAL LETTER I WITH MACRON +012C ; Lu # LATIN CAPITAL LETTER I WITH BREVE +012E ; Lu # LATIN CAPITAL LETTER I WITH OGONEK +0130 ; Lu # LATIN CAPITAL LETTER I WITH DOT ABOVE +0132 ; Lu # LATIN CAPITAL LIGATURE IJ +0134 ; Lu # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0136 ; Lu # LATIN CAPITAL LETTER K WITH CEDILLA +0139 ; Lu # LATIN CAPITAL LETTER L WITH ACUTE +013B ; Lu # LATIN CAPITAL LETTER L WITH CEDILLA +013D ; Lu # LATIN CAPITAL LETTER L WITH CARON +013F ; Lu # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141 ; Lu # LATIN CAPITAL LETTER L WITH STROKE +0143 ; Lu # LATIN CAPITAL LETTER N WITH ACUTE +0145 ; Lu # LATIN CAPITAL LETTER N WITH CEDILLA +0147 ; Lu # LATIN CAPITAL LETTER N WITH CARON +014A ; Lu # LATIN CAPITAL LETTER ENG +014C ; Lu # LATIN CAPITAL LETTER O WITH MACRON +014E ; Lu # LATIN CAPITAL LETTER O WITH BREVE +0150 ; Lu # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0152 ; Lu # LATIN CAPITAL LIGATURE OE +0154 ; Lu # LATIN CAPITAL LETTER R WITH ACUTE +0156 ; Lu # LATIN CAPITAL LETTER R WITH CEDILLA +0158 ; Lu # LATIN CAPITAL LETTER R WITH CARON +015A ; Lu # LATIN CAPITAL LETTER S WITH ACUTE +015C ; Lu # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015E ; Lu # LATIN CAPITAL LETTER S WITH CEDILLA +0160 ; Lu # LATIN CAPITAL LETTER S WITH CARON +0162 ; Lu # LATIN CAPITAL LETTER T WITH CEDILLA +0164 ; Lu # LATIN CAPITAL LETTER T WITH CARON +0166 ; Lu # LATIN CAPITAL LETTER T WITH STROKE +0168 ; Lu # LATIN CAPITAL LETTER U WITH TILDE +016A ; Lu # LATIN CAPITAL LETTER U WITH MACRON +016C ; Lu # LATIN CAPITAL LETTER U WITH BREVE +016E ; Lu # LATIN CAPITAL LETTER U WITH RING ABOVE +0170 ; Lu # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0172 ; Lu # LATIN CAPITAL LETTER U WITH OGONEK +0174 ; Lu # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0176 ; Lu # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178..0179 ; Lu # [2] LATIN CAPITAL LETTER Y WITH DIAERESIS..LATIN CAPITAL LETTER Z WITH ACUTE +017B ; Lu # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017D ; Lu # LATIN CAPITAL LETTER Z WITH CARON +0181..0182 ; Lu # [2] LATIN CAPITAL LETTER B WITH HOOK..LATIN CAPITAL LETTER B WITH TOPBAR +0184 ; Lu # LATIN CAPITAL LETTER TONE SIX +0186..0187 ; Lu # [2] LATIN CAPITAL LETTER OPEN O..LATIN CAPITAL LETTER C WITH HOOK +0189..018B ; Lu # [3] LATIN CAPITAL LETTER AFRICAN D..LATIN CAPITAL LETTER D WITH TOPBAR +018E..0191 ; Lu # [4] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER F WITH HOOK +0193..0194 ; Lu # [2] LATIN CAPITAL LETTER G WITH HOOK..LATIN CAPITAL LETTER GAMMA +0196..0198 ; Lu # [3] LATIN CAPITAL LETTER IOTA..LATIN CAPITAL LETTER K WITH HOOK +019C..019D ; Lu # [2] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER N WITH LEFT HOOK +019F..01A0 ; Lu # [2] LATIN CAPITAL LETTER O WITH MIDDLE TILDE..LATIN CAPITAL LETTER O WITH HORN +01A2 ; Lu # LATIN CAPITAL LETTER OI +01A4 ; Lu # LATIN CAPITAL LETTER P WITH HOOK +01A6..01A7 ; Lu # [2] LATIN LETTER YR..LATIN CAPITAL LETTER TONE TWO +01A9 ; Lu # LATIN CAPITAL LETTER ESH +01AC ; Lu # LATIN CAPITAL LETTER T WITH HOOK +01AE..01AF ; Lu # [2] LATIN CAPITAL LETTER T WITH RETROFLEX HOOK..LATIN CAPITAL LETTER U WITH HORN +01B1..01B3 ; Lu # [3] LATIN CAPITAL LETTER UPSILON..LATIN CAPITAL LETTER Y WITH HOOK +01B5 ; Lu # LATIN CAPITAL LETTER Z WITH STROKE +01B7..01B8 ; Lu # [2] LATIN CAPITAL LETTER EZH..LATIN CAPITAL LETTER EZH REVERSED +01BC ; Lu # LATIN CAPITAL LETTER TONE FIVE +01C4 ; Lu # LATIN CAPITAL LETTER DZ WITH CARON +01C7 ; Lu # LATIN CAPITAL LETTER LJ +01CA ; Lu # LATIN CAPITAL LETTER NJ +01CD ; Lu # LATIN CAPITAL LETTER A WITH CARON +01CF ; Lu # LATIN CAPITAL LETTER I WITH CARON +01D1 ; Lu # LATIN CAPITAL LETTER O WITH CARON +01D3 ; Lu # LATIN CAPITAL LETTER U WITH CARON +01D5 ; Lu # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +01D7 ; Lu # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01D9 ; Lu # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01DB ; Lu # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DE ; Lu # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +01E0 ; Lu # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +01E2 ; Lu # LATIN CAPITAL LETTER AE WITH MACRON +01E4 ; Lu # LATIN CAPITAL LETTER G WITH STROKE +01E6 ; Lu # LATIN CAPITAL LETTER G WITH CARON +01E8 ; Lu # LATIN CAPITAL LETTER K WITH CARON +01EA ; Lu # LATIN CAPITAL LETTER O WITH OGONEK +01EC ; Lu # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +01EE ; Lu # LATIN CAPITAL LETTER EZH WITH CARON +01F1 ; Lu # LATIN CAPITAL LETTER DZ +01F4 ; Lu # LATIN CAPITAL LETTER G WITH ACUTE +01F6..01F8 ; Lu # [3] LATIN CAPITAL LETTER HWAIR..LATIN CAPITAL LETTER N WITH GRAVE +01FA ; Lu # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +01FC ; Lu # LATIN CAPITAL LETTER AE WITH ACUTE +01FE ; Lu # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +0200 ; Lu # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0202 ; Lu # LATIN CAPITAL LETTER A WITH INVERTED BREVE +0204 ; Lu # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0206 ; Lu # LATIN CAPITAL LETTER E WITH INVERTED BREVE +0208 ; Lu # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020A ; Lu # LATIN CAPITAL LETTER I WITH INVERTED BREVE +020C ; Lu # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020E ; Lu # LATIN CAPITAL LETTER O WITH INVERTED BREVE +0210 ; Lu # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0212 ; Lu # LATIN CAPITAL LETTER R WITH INVERTED BREVE +0214 ; Lu # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0216 ; Lu # LATIN CAPITAL LETTER U WITH INVERTED BREVE +0218 ; Lu # LATIN CAPITAL LETTER S WITH COMMA BELOW +021A ; Lu # LATIN CAPITAL LETTER T WITH COMMA BELOW +021C ; Lu # LATIN CAPITAL LETTER YOGH +021E ; Lu # LATIN CAPITAL LETTER H WITH CARON +0220 ; Lu # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +0222 ; Lu # LATIN CAPITAL LETTER OU +0224 ; Lu # LATIN CAPITAL LETTER Z WITH HOOK +0226 ; Lu # LATIN CAPITAL LETTER A WITH DOT ABOVE +0228 ; Lu # LATIN CAPITAL LETTER E WITH CEDILLA +022A ; Lu # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +022C ; Lu # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022E ; Lu # LATIN CAPITAL LETTER O WITH DOT ABOVE +0230 ; Lu # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +0232 ; Lu # LATIN CAPITAL LETTER Y WITH MACRON +023A..023B ; Lu # [2] LATIN CAPITAL LETTER A WITH STROKE..LATIN CAPITAL LETTER C WITH STROKE +023D..023E ; Lu # [2] LATIN CAPITAL LETTER L WITH BAR..LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +0241 ; Lu # LATIN CAPITAL LETTER GLOTTAL STOP +0243..0246 ; Lu # [4] LATIN CAPITAL LETTER B WITH STROKE..LATIN CAPITAL LETTER E WITH STROKE +0248 ; Lu # LATIN CAPITAL LETTER J WITH STROKE +024A ; Lu # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +024C ; Lu # LATIN CAPITAL LETTER R WITH STROKE +024E ; Lu # LATIN CAPITAL LETTER Y WITH STROKE +0370 ; Lu # GREEK CAPITAL LETTER HETA +0372 ; Lu # GREEK CAPITAL LETTER ARCHAIC SAMPI +0376 ; Lu # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +037F ; Lu # GREEK CAPITAL LETTER YOT +0386 ; Lu # GREEK CAPITAL LETTER ALPHA WITH TONOS +0388..038A ; Lu # [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS +038C ; Lu # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E..038F ; Lu # [2] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER OMEGA WITH TONOS +0391..03A1 ; Lu # [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO +03A3..03AB ; Lu # [9] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03CF ; Lu # GREEK CAPITAL KAI SYMBOL +03D2..03D4 ; Lu # [3] GREEK UPSILON WITH HOOK SYMBOL..GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL +03D8 ; Lu # GREEK LETTER ARCHAIC KOPPA +03DA ; Lu # GREEK LETTER STIGMA +03DC ; Lu # GREEK LETTER DIGAMMA +03DE ; Lu # GREEK LETTER KOPPA +03E0 ; Lu # GREEK LETTER SAMPI +03E2 ; Lu # COPTIC CAPITAL LETTER SHEI +03E4 ; Lu # COPTIC CAPITAL LETTER FEI +03E6 ; Lu # COPTIC CAPITAL LETTER KHEI +03E8 ; Lu # COPTIC CAPITAL LETTER HORI +03EA ; Lu # COPTIC CAPITAL LETTER GANGIA +03EC ; Lu # COPTIC CAPITAL LETTER SHIMA +03EE ; Lu # COPTIC CAPITAL LETTER DEI +03F4 ; Lu # GREEK CAPITAL THETA SYMBOL +03F7 ; Lu # GREEK CAPITAL LETTER SHO +03F9..03FA ; Lu # [2] GREEK CAPITAL LUNATE SIGMA SYMBOL..GREEK CAPITAL LETTER SAN +03FD..042F ; Lu # [51] GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL..CYRILLIC CAPITAL LETTER YA +0460 ; Lu # CYRILLIC CAPITAL LETTER OMEGA +0462 ; Lu # CYRILLIC CAPITAL LETTER YAT +0464 ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED E +0466 ; Lu # CYRILLIC CAPITAL LETTER LITTLE YUS +0468 ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +046A ; Lu # CYRILLIC CAPITAL LETTER BIG YUS +046C ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046E ; Lu # CYRILLIC CAPITAL LETTER KSI +0470 ; Lu # CYRILLIC CAPITAL LETTER PSI +0472 ; Lu # CYRILLIC CAPITAL LETTER FITA +0474 ; Lu # CYRILLIC CAPITAL LETTER IZHITSA +0476 ; Lu # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0478 ; Lu # CYRILLIC CAPITAL LETTER UK +047A ; Lu # CYRILLIC CAPITAL LETTER ROUND OMEGA +047C ; Lu # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047E ; Lu # CYRILLIC CAPITAL LETTER OT +0480 ; Lu # CYRILLIC CAPITAL LETTER KOPPA +048A ; Lu # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +048C ; Lu # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +048E ; Lu # CYRILLIC CAPITAL LETTER ER WITH TICK +0490 ; Lu # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0492 ; Lu # CYRILLIC CAPITAL LETTER GHE WITH STROKE +0494 ; Lu # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +0496 ; Lu # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0498 ; Lu # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +049A ; Lu # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +049C ; Lu # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +049E ; Lu # CYRILLIC CAPITAL LETTER KA WITH STROKE +04A0 ; Lu # CYRILLIC CAPITAL LETTER BASHKIR KA +04A2 ; Lu # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04A4 ; Lu # CYRILLIC CAPITAL LIGATURE EN GHE +04A6 ; Lu # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +04A8 ; Lu # CYRILLIC CAPITAL LETTER ABKHASIAN HA +04AA ; Lu # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +04AC ; Lu # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +04AE ; Lu # CYRILLIC CAPITAL LETTER STRAIGHT U +04B0 ; Lu # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +04B2 ; Lu # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04B4 ; Lu # CYRILLIC CAPITAL LIGATURE TE TSE +04B6 ; Lu # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04B8 ; Lu # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +04BA ; Lu # CYRILLIC CAPITAL LETTER SHHA +04BC ; Lu # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BE ; Lu # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +04C0..04C1 ; Lu # [2] CYRILLIC LETTER PALOCHKA..CYRILLIC CAPITAL LETTER ZHE WITH BREVE +04C3 ; Lu # CYRILLIC CAPITAL LETTER KA WITH HOOK +04C5 ; Lu # CYRILLIC CAPITAL LETTER EL WITH TAIL +04C7 ; Lu # CYRILLIC CAPITAL LETTER EN WITH HOOK +04C9 ; Lu # CYRILLIC CAPITAL LETTER EN WITH TAIL +04CB ; Lu # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04CD ; Lu # CYRILLIC CAPITAL LETTER EM WITH TAIL +04D0 ; Lu # CYRILLIC CAPITAL LETTER A WITH BREVE +04D2 ; Lu # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D4 ; Lu # CYRILLIC CAPITAL LIGATURE A IE +04D6 ; Lu # CYRILLIC CAPITAL LETTER IE WITH BREVE +04D8 ; Lu # CYRILLIC CAPITAL LETTER SCHWA +04DA ; Lu # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04DC ; Lu # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +04DE ; Lu # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +04E0 ; Lu # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +04E2 ; Lu # CYRILLIC CAPITAL LETTER I WITH MACRON +04E4 ; Lu # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +04E6 ; Lu # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E8 ; Lu # CYRILLIC CAPITAL LETTER BARRED O +04EA ; Lu # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04EC ; Lu # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +04EE ; Lu # CYRILLIC CAPITAL LETTER U WITH MACRON +04F0 ; Lu # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F2 ; Lu # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04F4 ; Lu # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04F6 ; Lu # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +04F8 ; Lu # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +04FA ; Lu # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +04FC ; Lu # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FE ; Lu # CYRILLIC CAPITAL LETTER HA WITH STROKE +0500 ; Lu # CYRILLIC CAPITAL LETTER KOMI DE +0502 ; Lu # CYRILLIC CAPITAL LETTER KOMI DJE +0504 ; Lu # CYRILLIC CAPITAL LETTER KOMI ZJE +0506 ; Lu # CYRILLIC CAPITAL LETTER KOMI DZJE +0508 ; Lu # CYRILLIC CAPITAL LETTER KOMI LJE +050A ; Lu # CYRILLIC CAPITAL LETTER KOMI NJE +050C ; Lu # CYRILLIC CAPITAL LETTER KOMI SJE +050E ; Lu # CYRILLIC CAPITAL LETTER KOMI TJE +0510 ; Lu # CYRILLIC CAPITAL LETTER REVERSED ZE +0512 ; Lu # CYRILLIC CAPITAL LETTER EL WITH HOOK +0514 ; Lu # CYRILLIC CAPITAL LETTER LHA +0516 ; Lu # CYRILLIC CAPITAL LETTER RHA +0518 ; Lu # CYRILLIC CAPITAL LETTER YAE +051A ; Lu # CYRILLIC CAPITAL LETTER QA +051C ; Lu # CYRILLIC CAPITAL LETTER WE +051E ; Lu # CYRILLIC CAPITAL LETTER ALEUT KA +0520 ; Lu # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0522 ; Lu # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +0524 ; Lu # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +0526 ; Lu # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +0528 ; Lu # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +052A ; Lu # CYRILLIC CAPITAL LETTER DZZHE +052C ; Lu # CYRILLIC CAPITAL LETTER DCHE +052E ; Lu # CYRILLIC CAPITAL LETTER EL WITH DESCENDER +0531..0556 ; Lu # [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH +10A0..10C5 ; Lu # [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE +10C7 ; Lu # GEORGIAN CAPITAL LETTER YN +10CD ; Lu # GEORGIAN CAPITAL LETTER AEN +13A0..13F5 ; Lu # [86] CHEROKEE LETTER A..CHEROKEE LETTER MV +1E00 ; Lu # LATIN CAPITAL LETTER A WITH RING BELOW +1E02 ; Lu # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E04 ; Lu # LATIN CAPITAL LETTER B WITH DOT BELOW +1E06 ; Lu # LATIN CAPITAL LETTER B WITH LINE BELOW +1E08 ; Lu # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +1E0A ; Lu # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0C ; Lu # LATIN CAPITAL LETTER D WITH DOT BELOW +1E0E ; Lu # LATIN CAPITAL LETTER D WITH LINE BELOW +1E10 ; Lu # LATIN CAPITAL LETTER D WITH CEDILLA +1E12 ; Lu # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E14 ; Lu # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1E16 ; Lu # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E18 ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1A ; Lu # LATIN CAPITAL LETTER E WITH TILDE BELOW +1E1C ; Lu # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +1E1E ; Lu # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E20 ; Lu # LATIN CAPITAL LETTER G WITH MACRON +1E22 ; Lu # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E24 ; Lu # LATIN CAPITAL LETTER H WITH DOT BELOW +1E26 ; Lu # LATIN CAPITAL LETTER H WITH DIAERESIS +1E28 ; Lu # LATIN CAPITAL LETTER H WITH CEDILLA +1E2A ; Lu # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E2C ; Lu # LATIN CAPITAL LETTER I WITH TILDE BELOW +1E2E ; Lu # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +1E30 ; Lu # LATIN CAPITAL LETTER K WITH ACUTE +1E32 ; Lu # LATIN CAPITAL LETTER K WITH DOT BELOW +1E34 ; Lu # LATIN CAPITAL LETTER K WITH LINE BELOW +1E36 ; Lu # LATIN CAPITAL LETTER L WITH DOT BELOW +1E38 ; Lu # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3A ; Lu # LATIN CAPITAL LETTER L WITH LINE BELOW +1E3C ; Lu # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3E ; Lu # LATIN CAPITAL LETTER M WITH ACUTE +1E40 ; Lu # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E42 ; Lu # LATIN CAPITAL LETTER M WITH DOT BELOW +1E44 ; Lu # LATIN CAPITAL LETTER N WITH DOT ABOVE +1E46 ; Lu # LATIN CAPITAL LETTER N WITH DOT BELOW +1E48 ; Lu # LATIN CAPITAL LETTER N WITH LINE BELOW +1E4A ; Lu # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E4C ; Lu # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4E ; Lu # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +1E50 ; Lu # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1E52 ; Lu # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E54 ; Lu # LATIN CAPITAL LETTER P WITH ACUTE +1E56 ; Lu # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E58 ; Lu # LATIN CAPITAL LETTER R WITH DOT ABOVE +1E5A ; Lu # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5C ; Lu # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5E ; Lu # LATIN CAPITAL LETTER R WITH LINE BELOW +1E60 ; Lu # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E62 ; Lu # LATIN CAPITAL LETTER S WITH DOT BELOW +1E64 ; Lu # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +1E66 ; Lu # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E68 ; Lu # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6A ; Lu # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6C ; Lu # LATIN CAPITAL LETTER T WITH DOT BELOW +1E6E ; Lu # LATIN CAPITAL LETTER T WITH LINE BELOW +1E70 ; Lu # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E72 ; Lu # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E74 ; Lu # LATIN CAPITAL LETTER U WITH TILDE BELOW +1E76 ; Lu # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E78 ; Lu # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +1E7A ; Lu # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1E7C ; Lu # LATIN CAPITAL LETTER V WITH TILDE +1E7E ; Lu # LATIN CAPITAL LETTER V WITH DOT BELOW +1E80 ; Lu # LATIN CAPITAL LETTER W WITH GRAVE +1E82 ; Lu # LATIN CAPITAL LETTER W WITH ACUTE +1E84 ; Lu # LATIN CAPITAL LETTER W WITH DIAERESIS +1E86 ; Lu # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E88 ; Lu # LATIN CAPITAL LETTER W WITH DOT BELOW +1E8A ; Lu # LATIN CAPITAL LETTER X WITH DOT ABOVE +1E8C ; Lu # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8E ; Lu # LATIN CAPITAL LETTER Y WITH DOT ABOVE +1E90 ; Lu # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +1E92 ; Lu # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E94 ; Lu # LATIN CAPITAL LETTER Z WITH LINE BELOW +1E9E ; Lu # LATIN CAPITAL LETTER SHARP S +1EA0 ; Lu # LATIN CAPITAL LETTER A WITH DOT BELOW +1EA2 ; Lu # LATIN CAPITAL LETTER A WITH HOOK ABOVE +1EA4 ; Lu # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA6 ; Lu # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA8 ; Lu # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAA ; Lu # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EAC ; Lu # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAE ; Lu # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB0 ; Lu # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB2 ; Lu # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +1EB4 ; Lu # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB6 ; Lu # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EB8 ; Lu # LATIN CAPITAL LETTER E WITH DOT BELOW +1EBA ; Lu # LATIN CAPITAL LETTER E WITH HOOK ABOVE +1EBC ; Lu # LATIN CAPITAL LETTER E WITH TILDE +1EBE ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC0 ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC2 ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC4 ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC6 ; Lu # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC8 ; Lu # LATIN CAPITAL LETTER I WITH HOOK ABOVE +1ECA ; Lu # LATIN CAPITAL LETTER I WITH DOT BELOW +1ECC ; Lu # LATIN CAPITAL LETTER O WITH DOT BELOW +1ECE ; Lu # LATIN CAPITAL LETTER O WITH HOOK ABOVE +1ED0 ; Lu # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED2 ; Lu # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED4 ; Lu # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED6 ; Lu # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED8 ; Lu # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDA ; Lu # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDC ; Lu # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EDE ; Lu # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE0 ; Lu # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EE2 ; Lu # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1EE4 ; Lu # LATIN CAPITAL LETTER U WITH DOT BELOW +1EE6 ; Lu # LATIN CAPITAL LETTER U WITH HOOK ABOVE +1EE8 ; Lu # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEA ; Lu # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEC ; Lu # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EEE ; Lu # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EF0 ; Lu # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EF2 ; Lu # LATIN CAPITAL LETTER Y WITH GRAVE +1EF4 ; Lu # LATIN CAPITAL LETTER Y WITH DOT BELOW +1EF6 ; Lu # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF8 ; Lu # LATIN CAPITAL LETTER Y WITH TILDE +1EFA ; Lu # LATIN CAPITAL LETTER MIDDLE-WELSH LL +1EFC ; Lu # LATIN CAPITAL LETTER MIDDLE-WELSH V +1EFE ; Lu # LATIN CAPITAL LETTER Y WITH LOOP +1F08..1F0F ; Lu # [8] GREEK CAPITAL LETTER ALPHA WITH PSILI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F18..1F1D ; Lu # [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F28..1F2F ; Lu # [8] GREEK CAPITAL LETTER ETA WITH PSILI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F38..1F3F ; Lu # [8] GREEK CAPITAL LETTER IOTA WITH PSILI..GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +1F48..1F4D ; Lu # [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F59 ; Lu # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F5B ; Lu # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F5D ; Lu # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F5F ; Lu # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F68..1F6F ; Lu # [8] GREEK CAPITAL LETTER OMEGA WITH PSILI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1FB8..1FBB ; Lu # [4] GREEK CAPITAL LETTER ALPHA WITH VRACHY..GREEK CAPITAL LETTER ALPHA WITH OXIA +1FC8..1FCB ; Lu # [4] GREEK CAPITAL LETTER EPSILON WITH VARIA..GREEK CAPITAL LETTER ETA WITH OXIA +1FD8..1FDB ; Lu # [4] GREEK CAPITAL LETTER IOTA WITH VRACHY..GREEK CAPITAL LETTER IOTA WITH OXIA +1FE8..1FEC ; Lu # [5] GREEK CAPITAL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA +1FF8..1FFB ; Lu # [4] GREEK CAPITAL LETTER OMICRON WITH VARIA..GREEK CAPITAL LETTER OMEGA WITH OXIA +2102 ; Lu # DOUBLE-STRUCK CAPITAL C +2107 ; Lu # EULER CONSTANT +210B..210D ; Lu # [3] SCRIPT CAPITAL H..DOUBLE-STRUCK CAPITAL H +2110..2112 ; Lu # [3] SCRIPT CAPITAL I..SCRIPT CAPITAL L +2115 ; Lu # DOUBLE-STRUCK CAPITAL N +2119..211D ; Lu # [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R +2124 ; Lu # DOUBLE-STRUCK CAPITAL Z +2126 ; Lu # OHM SIGN +2128 ; Lu # BLACK-LETTER CAPITAL Z +212A..212D ; Lu # [4] KELVIN SIGN..BLACK-LETTER CAPITAL C +2130..2133 ; Lu # [4] SCRIPT CAPITAL E..SCRIPT CAPITAL M +213E..213F ; Lu # [2] DOUBLE-STRUCK CAPITAL GAMMA..DOUBLE-STRUCK CAPITAL PI +2145 ; Lu # DOUBLE-STRUCK ITALIC CAPITAL D +2183 ; Lu # ROMAN NUMERAL REVERSED ONE HUNDRED +2C00..2C2E ; Lu # [47] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +2C60 ; Lu # LATIN CAPITAL LETTER L WITH DOUBLE BAR +2C62..2C64 ; Lu # [3] LATIN CAPITAL LETTER L WITH MIDDLE TILDE..LATIN CAPITAL LETTER R WITH TAIL +2C67 ; Lu # LATIN CAPITAL LETTER H WITH DESCENDER +2C69 ; Lu # LATIN CAPITAL LETTER K WITH DESCENDER +2C6B ; Lu # LATIN CAPITAL LETTER Z WITH DESCENDER +2C6D..2C70 ; Lu # [4] LATIN CAPITAL LETTER ALPHA..LATIN CAPITAL LETTER TURNED ALPHA +2C72 ; Lu # LATIN CAPITAL LETTER W WITH HOOK +2C75 ; Lu # LATIN CAPITAL LETTER HALF H +2C7E..2C80 ; Lu # [3] LATIN CAPITAL LETTER S WITH SWASH TAIL..COPTIC CAPITAL LETTER ALFA +2C82 ; Lu # COPTIC CAPITAL LETTER VIDA +2C84 ; Lu # COPTIC CAPITAL LETTER GAMMA +2C86 ; Lu # COPTIC CAPITAL LETTER DALDA +2C88 ; Lu # COPTIC CAPITAL LETTER EIE +2C8A ; Lu # COPTIC CAPITAL LETTER SOU +2C8C ; Lu # COPTIC CAPITAL LETTER ZATA +2C8E ; Lu # COPTIC CAPITAL LETTER HATE +2C90 ; Lu # COPTIC CAPITAL LETTER THETHE +2C92 ; Lu # COPTIC CAPITAL LETTER IAUDA +2C94 ; Lu # COPTIC CAPITAL LETTER KAPA +2C96 ; Lu # COPTIC CAPITAL LETTER LAULA +2C98 ; Lu # COPTIC CAPITAL LETTER MI +2C9A ; Lu # COPTIC CAPITAL LETTER NI +2C9C ; Lu # COPTIC CAPITAL LETTER KSI +2C9E ; Lu # COPTIC CAPITAL LETTER O +2CA0 ; Lu # COPTIC CAPITAL LETTER PI +2CA2 ; Lu # COPTIC CAPITAL LETTER RO +2CA4 ; Lu # COPTIC CAPITAL LETTER SIMA +2CA6 ; Lu # COPTIC CAPITAL LETTER TAU +2CA8 ; Lu # COPTIC CAPITAL LETTER UA +2CAA ; Lu # COPTIC CAPITAL LETTER FI +2CAC ; Lu # COPTIC CAPITAL LETTER KHI +2CAE ; Lu # COPTIC CAPITAL LETTER PSI +2CB0 ; Lu # COPTIC CAPITAL LETTER OOU +2CB2 ; Lu # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB4 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CB6 ; Lu # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2CB8 ; Lu # COPTIC CAPITAL LETTER DIALECT-P KAPA +2CBA ; Lu # COPTIC CAPITAL LETTER DIALECT-P NI +2CBC ; Lu # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2CBE ; Lu # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC0 ; Lu # COPTIC CAPITAL LETTER SAMPI +2CC2 ; Lu # COPTIC CAPITAL LETTER CROSSED SHEI +2CC4 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC6 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC ESH +2CC8 ; Lu # COPTIC CAPITAL LETTER AKHMIMIC KHEI +2CCA ; Lu # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCC ; Lu # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCE ; Lu # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD0 ; Lu # COPTIC CAPITAL LETTER L-SHAPED HA +2CD2 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD4 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC HAT +2CD6 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +2CD8 ; Lu # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDA ; Lu # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDC ; Lu # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +2CDE ; Lu # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE0 ; Lu # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE2 ; Lu # COPTIC CAPITAL LETTER OLD NUBIAN WAU +2CEB ; Lu # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CED ; Lu # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CF2 ; Lu # COPTIC CAPITAL LETTER BOHAIRIC KHEI +A640 ; Lu # CYRILLIC CAPITAL LETTER ZEMLYA +A642 ; Lu # CYRILLIC CAPITAL LETTER DZELO +A644 ; Lu # CYRILLIC CAPITAL LETTER REVERSED DZE +A646 ; Lu # CYRILLIC CAPITAL LETTER IOTA +A648 ; Lu # CYRILLIC CAPITAL LETTER DJERV +A64A ; Lu # CYRILLIC CAPITAL LETTER MONOGRAPH UK +A64C ; Lu # CYRILLIC CAPITAL LETTER BROAD OMEGA +A64E ; Lu # CYRILLIC CAPITAL LETTER NEUTRAL YER +A650 ; Lu # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +A652 ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED YAT +A654 ; Lu # CYRILLIC CAPITAL LETTER REVERSED YU +A656 ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED A +A658 ; Lu # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +A65A ; Lu # CYRILLIC CAPITAL LETTER BLENDED YUS +A65C ; Lu # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +A65E ; Lu # CYRILLIC CAPITAL LETTER YN +A660 ; Lu # CYRILLIC CAPITAL LETTER REVERSED TSE +A662 ; Lu # CYRILLIC CAPITAL LETTER SOFT DE +A664 ; Lu # CYRILLIC CAPITAL LETTER SOFT EL +A666 ; Lu # CYRILLIC CAPITAL LETTER SOFT EM +A668 ; Lu # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A ; Lu # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C ; Lu # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +A680 ; Lu # CYRILLIC CAPITAL LETTER DWE +A682 ; Lu # CYRILLIC CAPITAL LETTER DZWE +A684 ; Lu # CYRILLIC CAPITAL LETTER ZHWE +A686 ; Lu # CYRILLIC CAPITAL LETTER CCHE +A688 ; Lu # CYRILLIC CAPITAL LETTER DZZE +A68A ; Lu # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +A68C ; Lu # CYRILLIC CAPITAL LETTER TWE +A68E ; Lu # CYRILLIC CAPITAL LETTER TSWE +A690 ; Lu # CYRILLIC CAPITAL LETTER TSSE +A692 ; Lu # CYRILLIC CAPITAL LETTER TCHE +A694 ; Lu # CYRILLIC CAPITAL LETTER HWE +A696 ; Lu # CYRILLIC CAPITAL LETTER SHWE +A698 ; Lu # CYRILLIC CAPITAL LETTER DOUBLE O +A69A ; Lu # CYRILLIC CAPITAL LETTER CROSSED O +A722 ; Lu # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A724 ; Lu # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +A726 ; Lu # LATIN CAPITAL LETTER HENG +A728 ; Lu # LATIN CAPITAL LETTER TZ +A72A ; Lu # LATIN CAPITAL LETTER TRESILLO +A72C ; Lu # LATIN CAPITAL LETTER CUATRILLO +A72E ; Lu # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +A732 ; Lu # LATIN CAPITAL LETTER AA +A734 ; Lu # LATIN CAPITAL LETTER AO +A736 ; Lu # LATIN CAPITAL LETTER AU +A738 ; Lu # LATIN CAPITAL LETTER AV +A73A ; Lu # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73C ; Lu # LATIN CAPITAL LETTER AY +A73E ; Lu # LATIN CAPITAL LETTER REVERSED C WITH DOT +A740 ; Lu # LATIN CAPITAL LETTER K WITH STROKE +A742 ; Lu # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A744 ; Lu # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +A746 ; Lu # LATIN CAPITAL LETTER BROKEN L +A748 ; Lu # LATIN CAPITAL LETTER L WITH HIGH STROKE +A74A ; Lu # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +A74C ; Lu # LATIN CAPITAL LETTER O WITH LOOP +A74E ; Lu # LATIN CAPITAL LETTER OO +A750 ; Lu # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +A752 ; Lu # LATIN CAPITAL LETTER P WITH FLOURISH +A754 ; Lu # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A756 ; Lu # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A758 ; Lu # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +A75A ; Lu # LATIN CAPITAL LETTER R ROTUNDA +A75C ; Lu # LATIN CAPITAL LETTER RUM ROTUNDA +A75E ; Lu # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +A760 ; Lu # LATIN CAPITAL LETTER VY +A762 ; Lu # LATIN CAPITAL LETTER VISIGOTHIC Z +A764 ; Lu # LATIN CAPITAL LETTER THORN WITH STROKE +A766 ; Lu # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +A768 ; Lu # LATIN CAPITAL LETTER VEND +A76A ; Lu # LATIN CAPITAL LETTER ET +A76C ; Lu # LATIN CAPITAL LETTER IS +A76E ; Lu # LATIN CAPITAL LETTER CON +A779 ; Lu # LATIN CAPITAL LETTER INSULAR D +A77B ; Lu # LATIN CAPITAL LETTER INSULAR F +A77D..A77E ; Lu # [2] LATIN CAPITAL LETTER INSULAR G..LATIN CAPITAL LETTER TURNED INSULAR G +A780 ; Lu # LATIN CAPITAL LETTER TURNED L +A782 ; Lu # LATIN CAPITAL LETTER INSULAR R +A784 ; Lu # LATIN CAPITAL LETTER INSULAR S +A786 ; Lu # LATIN CAPITAL LETTER INSULAR T +A78B ; Lu # LATIN CAPITAL LETTER SALTILLO +A78D ; Lu # LATIN CAPITAL LETTER TURNED H +A790 ; Lu # LATIN CAPITAL LETTER N WITH DESCENDER +A792 ; Lu # LATIN CAPITAL LETTER C WITH BAR +A796 ; Lu # LATIN CAPITAL LETTER B WITH FLOURISH +A798 ; Lu # LATIN CAPITAL LETTER F WITH STROKE +A79A ; Lu # LATIN CAPITAL LETTER VOLAPUK AE +A79C ; Lu # LATIN CAPITAL LETTER VOLAPUK OE +A79E ; Lu # LATIN CAPITAL LETTER VOLAPUK UE +A7A0 ; Lu # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +A7A2 ; Lu # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +A7A4 ; Lu # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +A7A6 ; Lu # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +A7A8 ; Lu # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +A7AA..A7AE ; Lu # [5] LATIN CAPITAL LETTER H WITH HOOK..LATIN CAPITAL LETTER SMALL CAPITAL I +A7B0..A7B4 ; Lu # [5] LATIN CAPITAL LETTER TURNED K..LATIN CAPITAL LETTER BETA +A7B6 ; Lu # LATIN CAPITAL LETTER OMEGA +FF21..FF3A ; Lu # [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z +10400..10427 ; Lu # [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW +104B0..104D3 ; Lu # [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA +10C80..10CB2 ; Lu # [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US +118A0..118BF ; Lu # [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO +1D400..1D419 ; Lu # [26] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL BOLD CAPITAL Z +1D434..1D44D ; Lu # [26] MATHEMATICAL ITALIC CAPITAL A..MATHEMATICAL ITALIC CAPITAL Z +1D468..1D481 ; Lu # [26] MATHEMATICAL BOLD ITALIC CAPITAL A..MATHEMATICAL BOLD ITALIC CAPITAL Z +1D49C ; Lu # MATHEMATICAL SCRIPT CAPITAL A +1D49E..1D49F ; Lu # [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D +1D4A2 ; Lu # MATHEMATICAL SCRIPT CAPITAL G +1D4A5..1D4A6 ; Lu # [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K +1D4A9..1D4AC ; Lu # [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q +1D4AE..1D4B5 ; Lu # [8] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT CAPITAL Z +1D4D0..1D4E9 ; Lu # [26] MATHEMATICAL BOLD SCRIPT CAPITAL A..MATHEMATICAL BOLD SCRIPT CAPITAL Z +1D504..1D505 ; Lu # [2] MATHEMATICAL FRAKTUR CAPITAL A..MATHEMATICAL FRAKTUR CAPITAL B +1D507..1D50A ; Lu # [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G +1D50D..1D514 ; Lu # [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q +1D516..1D51C ; Lu # [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y +1D538..1D539 ; Lu # [2] MATHEMATICAL DOUBLE-STRUCK CAPITAL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B..1D53E ; Lu # [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540..1D544 ; Lu # [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 ; Lu # MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A..1D550 ; Lu # [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D56C..1D585 ; Lu # [26] MATHEMATICAL BOLD FRAKTUR CAPITAL A..MATHEMATICAL BOLD FRAKTUR CAPITAL Z +1D5A0..1D5B9 ; Lu # [26] MATHEMATICAL SANS-SERIF CAPITAL A..MATHEMATICAL SANS-SERIF CAPITAL Z +1D5D4..1D5ED ; Lu # [26] MATHEMATICAL SANS-SERIF BOLD CAPITAL A..MATHEMATICAL SANS-SERIF BOLD CAPITAL Z +1D608..1D621 ; Lu # [26] MATHEMATICAL SANS-SERIF ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z +1D63C..1D655 ; Lu # [26] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z +1D670..1D689 ; Lu # [26] MATHEMATICAL MONOSPACE CAPITAL A..MATHEMATICAL MONOSPACE CAPITAL Z +1D6A8..1D6C0 ; Lu # [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA +1D6E2..1D6FA ; Lu # [25] MATHEMATICAL ITALIC CAPITAL ALPHA..MATHEMATICAL ITALIC CAPITAL OMEGA +1D71C..1D734 ; Lu # [25] MATHEMATICAL BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D756..1D76E ; Lu # [25] MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D790..1D7A8 ; Lu # [25] MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7CA ; Lu # MATHEMATICAL BOLD CAPITAL DIGAMMA +1E900..1E921 ; Lu # [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA + +# Total code points: 1702 + +# ================================================ + +# General_Category=Lowercase_Letter + +0061..007A ; Ll # [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z +00B5 ; Ll # MICRO SIGN +00DF..00F6 ; Ll # [24] LATIN SMALL LETTER SHARP S..LATIN SMALL LETTER O WITH DIAERESIS +00F8..00FF ; Ll # [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS +0101 ; Ll # LATIN SMALL LETTER A WITH MACRON +0103 ; Ll # LATIN SMALL LETTER A WITH BREVE +0105 ; Ll # LATIN SMALL LETTER A WITH OGONEK +0107 ; Ll # LATIN SMALL LETTER C WITH ACUTE +0109 ; Ll # LATIN SMALL LETTER C WITH CIRCUMFLEX +010B ; Ll # LATIN SMALL LETTER C WITH DOT ABOVE +010D ; Ll # LATIN SMALL LETTER C WITH CARON +010F ; Ll # LATIN SMALL LETTER D WITH CARON +0111 ; Ll # LATIN SMALL LETTER D WITH STROKE +0113 ; Ll # LATIN SMALL LETTER E WITH MACRON +0115 ; Ll # LATIN SMALL LETTER E WITH BREVE +0117 ; Ll # LATIN SMALL LETTER E WITH DOT ABOVE +0119 ; Ll # LATIN SMALL LETTER E WITH OGONEK +011B ; Ll # LATIN SMALL LETTER E WITH CARON +011D ; Ll # LATIN SMALL LETTER G WITH CIRCUMFLEX +011F ; Ll # LATIN SMALL LETTER G WITH BREVE +0121 ; Ll # LATIN SMALL LETTER G WITH DOT ABOVE +0123 ; Ll # LATIN SMALL LETTER G WITH CEDILLA +0125 ; Ll # LATIN SMALL LETTER H WITH CIRCUMFLEX +0127 ; Ll # LATIN SMALL LETTER H WITH STROKE +0129 ; Ll # LATIN SMALL LETTER I WITH TILDE +012B ; Ll # LATIN SMALL LETTER I WITH MACRON +012D ; Ll # LATIN SMALL LETTER I WITH BREVE +012F ; Ll # LATIN SMALL LETTER I WITH OGONEK +0131 ; Ll # LATIN SMALL LETTER DOTLESS I +0133 ; Ll # LATIN SMALL LIGATURE IJ +0135 ; Ll # LATIN SMALL LETTER J WITH CIRCUMFLEX +0137..0138 ; Ll # [2] LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA +013A ; Ll # LATIN SMALL LETTER L WITH ACUTE +013C ; Ll # LATIN SMALL LETTER L WITH CEDILLA +013E ; Ll # LATIN SMALL LETTER L WITH CARON +0140 ; Ll # LATIN SMALL LETTER L WITH MIDDLE DOT +0142 ; Ll # LATIN SMALL LETTER L WITH STROKE +0144 ; Ll # LATIN SMALL LETTER N WITH ACUTE +0146 ; Ll # LATIN SMALL LETTER N WITH CEDILLA +0148..0149 ; Ll # [2] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014B ; Ll # LATIN SMALL LETTER ENG +014D ; Ll # LATIN SMALL LETTER O WITH MACRON +014F ; Ll # LATIN SMALL LETTER O WITH BREVE +0151 ; Ll # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0153 ; Ll # LATIN SMALL LIGATURE OE +0155 ; Ll # LATIN SMALL LETTER R WITH ACUTE +0157 ; Ll # LATIN SMALL LETTER R WITH CEDILLA +0159 ; Ll # LATIN SMALL LETTER R WITH CARON +015B ; Ll # LATIN SMALL LETTER S WITH ACUTE +015D ; Ll # LATIN SMALL LETTER S WITH CIRCUMFLEX +015F ; Ll # LATIN SMALL LETTER S WITH CEDILLA +0161 ; Ll # LATIN SMALL LETTER S WITH CARON +0163 ; Ll # LATIN SMALL LETTER T WITH CEDILLA +0165 ; Ll # LATIN SMALL LETTER T WITH CARON +0167 ; Ll # LATIN SMALL LETTER T WITH STROKE +0169 ; Ll # LATIN SMALL LETTER U WITH TILDE +016B ; Ll # LATIN SMALL LETTER U WITH MACRON +016D ; Ll # LATIN SMALL LETTER U WITH BREVE +016F ; Ll # LATIN SMALL LETTER U WITH RING ABOVE +0171 ; Ll # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0173 ; Ll # LATIN SMALL LETTER U WITH OGONEK +0175 ; Ll # LATIN SMALL LETTER W WITH CIRCUMFLEX +0177 ; Ll # LATIN SMALL LETTER Y WITH CIRCUMFLEX +017A ; Ll # LATIN SMALL LETTER Z WITH ACUTE +017C ; Ll # LATIN SMALL LETTER Z WITH DOT ABOVE +017E..0180 ; Ll # [3] LATIN SMALL LETTER Z WITH CARON..LATIN SMALL LETTER B WITH STROKE +0183 ; Ll # LATIN SMALL LETTER B WITH TOPBAR +0185 ; Ll # LATIN SMALL LETTER TONE SIX +0188 ; Ll # LATIN SMALL LETTER C WITH HOOK +018C..018D ; Ll # [2] LATIN SMALL LETTER D WITH TOPBAR..LATIN SMALL LETTER TURNED DELTA +0192 ; Ll # LATIN SMALL LETTER F WITH HOOK +0195 ; Ll # LATIN SMALL LETTER HV +0199..019B ; Ll # [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE +019E ; Ll # LATIN SMALL LETTER N WITH LONG RIGHT LEG +01A1 ; Ll # LATIN SMALL LETTER O WITH HORN +01A3 ; Ll # LATIN SMALL LETTER OI +01A5 ; Ll # LATIN SMALL LETTER P WITH HOOK +01A8 ; Ll # LATIN SMALL LETTER TONE TWO +01AA..01AB ; Ll # [2] LATIN LETTER REVERSED ESH LOOP..LATIN SMALL LETTER T WITH PALATAL HOOK +01AD ; Ll # LATIN SMALL LETTER T WITH HOOK +01B0 ; Ll # LATIN SMALL LETTER U WITH HORN +01B4 ; Ll # LATIN SMALL LETTER Y WITH HOOK +01B6 ; Ll # LATIN SMALL LETTER Z WITH STROKE +01B9..01BA ; Ll # [2] LATIN SMALL LETTER EZH REVERSED..LATIN SMALL LETTER EZH WITH TAIL +01BD..01BF ; Ll # [3] LATIN SMALL LETTER TONE FIVE..LATIN LETTER WYNN +01C6 ; Ll # LATIN SMALL LETTER DZ WITH CARON +01C9 ; Ll # LATIN SMALL LETTER LJ +01CC ; Ll # LATIN SMALL LETTER NJ +01CE ; Ll # LATIN SMALL LETTER A WITH CARON +01D0 ; Ll # LATIN SMALL LETTER I WITH CARON +01D2 ; Ll # LATIN SMALL LETTER O WITH CARON +01D4 ; Ll # LATIN SMALL LETTER U WITH CARON +01D6 ; Ll # LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D8 ; Ll # LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01DA ; Ll # LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01DC..01DD ; Ll # [2] LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E +01DF ; Ll # LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +01E1 ; Ll # LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +01E3 ; Ll # LATIN SMALL LETTER AE WITH MACRON +01E5 ; Ll # LATIN SMALL LETTER G WITH STROKE +01E7 ; Ll # LATIN SMALL LETTER G WITH CARON +01E9 ; Ll # LATIN SMALL LETTER K WITH CARON +01EB ; Ll # LATIN SMALL LETTER O WITH OGONEK +01ED ; Ll # LATIN SMALL LETTER O WITH OGONEK AND MACRON +01EF..01F0 ; Ll # [2] LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON +01F3 ; Ll # LATIN SMALL LETTER DZ +01F5 ; Ll # LATIN SMALL LETTER G WITH ACUTE +01F9 ; Ll # LATIN SMALL LETTER N WITH GRAVE +01FB ; Ll # LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +01FD ; Ll # LATIN SMALL LETTER AE WITH ACUTE +01FF ; Ll # LATIN SMALL LETTER O WITH STROKE AND ACUTE +0201 ; Ll # LATIN SMALL LETTER A WITH DOUBLE GRAVE +0203 ; Ll # LATIN SMALL LETTER A WITH INVERTED BREVE +0205 ; Ll # LATIN SMALL LETTER E WITH DOUBLE GRAVE +0207 ; Ll # LATIN SMALL LETTER E WITH INVERTED BREVE +0209 ; Ll # LATIN SMALL LETTER I WITH DOUBLE GRAVE +020B ; Ll # LATIN SMALL LETTER I WITH INVERTED BREVE +020D ; Ll # LATIN SMALL LETTER O WITH DOUBLE GRAVE +020F ; Ll # LATIN SMALL LETTER O WITH INVERTED BREVE +0211 ; Ll # LATIN SMALL LETTER R WITH DOUBLE GRAVE +0213 ; Ll # LATIN SMALL LETTER R WITH INVERTED BREVE +0215 ; Ll # LATIN SMALL LETTER U WITH DOUBLE GRAVE +0217 ; Ll # LATIN SMALL LETTER U WITH INVERTED BREVE +0219 ; Ll # LATIN SMALL LETTER S WITH COMMA BELOW +021B ; Ll # LATIN SMALL LETTER T WITH COMMA BELOW +021D ; Ll # LATIN SMALL LETTER YOGH +021F ; Ll # LATIN SMALL LETTER H WITH CARON +0221 ; Ll # LATIN SMALL LETTER D WITH CURL +0223 ; Ll # LATIN SMALL LETTER OU +0225 ; Ll # LATIN SMALL LETTER Z WITH HOOK +0227 ; Ll # LATIN SMALL LETTER A WITH DOT ABOVE +0229 ; Ll # LATIN SMALL LETTER E WITH CEDILLA +022B ; Ll # LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +022D ; Ll # LATIN SMALL LETTER O WITH TILDE AND MACRON +022F ; Ll # LATIN SMALL LETTER O WITH DOT ABOVE +0231 ; Ll # LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +0233..0239 ; Ll # [7] LATIN SMALL LETTER Y WITH MACRON..LATIN SMALL LETTER QP DIGRAPH +023C ; Ll # LATIN SMALL LETTER C WITH STROKE +023F..0240 ; Ll # [2] LATIN SMALL LETTER S WITH SWASH TAIL..LATIN SMALL LETTER Z WITH SWASH TAIL +0242 ; Ll # LATIN SMALL LETTER GLOTTAL STOP +0247 ; Ll # LATIN SMALL LETTER E WITH STROKE +0249 ; Ll # LATIN SMALL LETTER J WITH STROKE +024B ; Ll # LATIN SMALL LETTER Q WITH HOOK TAIL +024D ; Ll # LATIN SMALL LETTER R WITH STROKE +024F..0293 ; Ll # [69] LATIN SMALL LETTER Y WITH STROKE..LATIN SMALL LETTER EZH WITH CURL +0295..02AF ; Ll # [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +0371 ; Ll # GREEK SMALL LETTER HETA +0373 ; Ll # GREEK SMALL LETTER ARCHAIC SAMPI +0377 ; Ll # GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +037B..037D ; Ll # [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +0390 ; Ll # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AC..03CE ; Ll # [35] GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER OMEGA WITH TONOS +03D0..03D1 ; Ll # [2] GREEK BETA SYMBOL..GREEK THETA SYMBOL +03D5..03D7 ; Ll # [3] GREEK PHI SYMBOL..GREEK KAI SYMBOL +03D9 ; Ll # GREEK SMALL LETTER ARCHAIC KOPPA +03DB ; Ll # GREEK SMALL LETTER STIGMA +03DD ; Ll # GREEK SMALL LETTER DIGAMMA +03DF ; Ll # GREEK SMALL LETTER KOPPA +03E1 ; Ll # GREEK SMALL LETTER SAMPI +03E3 ; Ll # COPTIC SMALL LETTER SHEI +03E5 ; Ll # COPTIC SMALL LETTER FEI +03E7 ; Ll # COPTIC SMALL LETTER KHEI +03E9 ; Ll # COPTIC SMALL LETTER HORI +03EB ; Ll # COPTIC SMALL LETTER GANGIA +03ED ; Ll # COPTIC SMALL LETTER SHIMA +03EF..03F3 ; Ll # [5] COPTIC SMALL LETTER DEI..GREEK LETTER YOT +03F5 ; Ll # GREEK LUNATE EPSILON SYMBOL +03F8 ; Ll # GREEK SMALL LETTER SHO +03FB..03FC ; Ll # [2] GREEK SMALL LETTER SAN..GREEK RHO WITH STROKE SYMBOL +0430..045F ; Ll # [48] CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE +0461 ; Ll # CYRILLIC SMALL LETTER OMEGA +0463 ; Ll # CYRILLIC SMALL LETTER YAT +0465 ; Ll # CYRILLIC SMALL LETTER IOTIFIED E +0467 ; Ll # CYRILLIC SMALL LETTER LITTLE YUS +0469 ; Ll # CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +046B ; Ll # CYRILLIC SMALL LETTER BIG YUS +046D ; Ll # CYRILLIC SMALL LETTER IOTIFIED BIG YUS +046F ; Ll # CYRILLIC SMALL LETTER KSI +0471 ; Ll # CYRILLIC SMALL LETTER PSI +0473 ; Ll # CYRILLIC SMALL LETTER FITA +0475 ; Ll # CYRILLIC SMALL LETTER IZHITSA +0477 ; Ll # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0479 ; Ll # CYRILLIC SMALL LETTER UK +047B ; Ll # CYRILLIC SMALL LETTER ROUND OMEGA +047D ; Ll # CYRILLIC SMALL LETTER OMEGA WITH TITLO +047F ; Ll # CYRILLIC SMALL LETTER OT +0481 ; Ll # CYRILLIC SMALL LETTER KOPPA +048B ; Ll # CYRILLIC SMALL LETTER SHORT I WITH TAIL +048D ; Ll # CYRILLIC SMALL LETTER SEMISOFT SIGN +048F ; Ll # CYRILLIC SMALL LETTER ER WITH TICK +0491 ; Ll # CYRILLIC SMALL LETTER GHE WITH UPTURN +0493 ; Ll # CYRILLIC SMALL LETTER GHE WITH STROKE +0495 ; Ll # CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK +0497 ; Ll # CYRILLIC SMALL LETTER ZHE WITH DESCENDER +0499 ; Ll # CYRILLIC SMALL LETTER ZE WITH DESCENDER +049B ; Ll # CYRILLIC SMALL LETTER KA WITH DESCENDER +049D ; Ll # CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE +049F ; Ll # CYRILLIC SMALL LETTER KA WITH STROKE +04A1 ; Ll # CYRILLIC SMALL LETTER BASHKIR KA +04A3 ; Ll # CYRILLIC SMALL LETTER EN WITH DESCENDER +04A5 ; Ll # CYRILLIC SMALL LIGATURE EN GHE +04A7 ; Ll # CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK +04A9 ; Ll # CYRILLIC SMALL LETTER ABKHASIAN HA +04AB ; Ll # CYRILLIC SMALL LETTER ES WITH DESCENDER +04AD ; Ll # CYRILLIC SMALL LETTER TE WITH DESCENDER +04AF ; Ll # CYRILLIC SMALL LETTER STRAIGHT U +04B1 ; Ll # CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE +04B3 ; Ll # CYRILLIC SMALL LETTER HA WITH DESCENDER +04B5 ; Ll # CYRILLIC SMALL LIGATURE TE TSE +04B7 ; Ll # CYRILLIC SMALL LETTER CHE WITH DESCENDER +04B9 ; Ll # CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE +04BB ; Ll # CYRILLIC SMALL LETTER SHHA +04BD ; Ll # CYRILLIC SMALL LETTER ABKHASIAN CHE +04BF ; Ll # CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER +04C2 ; Ll # CYRILLIC SMALL LETTER ZHE WITH BREVE +04C4 ; Ll # CYRILLIC SMALL LETTER KA WITH HOOK +04C6 ; Ll # CYRILLIC SMALL LETTER EL WITH TAIL +04C8 ; Ll # CYRILLIC SMALL LETTER EN WITH HOOK +04CA ; Ll # CYRILLIC SMALL LETTER EN WITH TAIL +04CC ; Ll # CYRILLIC SMALL LETTER KHAKASSIAN CHE +04CE..04CF ; Ll # [2] CYRILLIC SMALL LETTER EM WITH TAIL..CYRILLIC SMALL LETTER PALOCHKA +04D1 ; Ll # CYRILLIC SMALL LETTER A WITH BREVE +04D3 ; Ll # CYRILLIC SMALL LETTER A WITH DIAERESIS +04D5 ; Ll # CYRILLIC SMALL LIGATURE A IE +04D7 ; Ll # CYRILLIC SMALL LETTER IE WITH BREVE +04D9 ; Ll # CYRILLIC SMALL LETTER SCHWA +04DB ; Ll # CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +04DD ; Ll # CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +04DF ; Ll # CYRILLIC SMALL LETTER ZE WITH DIAERESIS +04E1 ; Ll # CYRILLIC SMALL LETTER ABKHASIAN DZE +04E3 ; Ll # CYRILLIC SMALL LETTER I WITH MACRON +04E5 ; Ll # CYRILLIC SMALL LETTER I WITH DIAERESIS +04E7 ; Ll # CYRILLIC SMALL LETTER O WITH DIAERESIS +04E9 ; Ll # CYRILLIC SMALL LETTER BARRED O +04EB ; Ll # CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +04ED ; Ll # CYRILLIC SMALL LETTER E WITH DIAERESIS +04EF ; Ll # CYRILLIC SMALL LETTER U WITH MACRON +04F1 ; Ll # CYRILLIC SMALL LETTER U WITH DIAERESIS +04F3 ; Ll # CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +04F5 ; Ll # CYRILLIC SMALL LETTER CHE WITH DIAERESIS +04F7 ; Ll # CYRILLIC SMALL LETTER GHE WITH DESCENDER +04F9 ; Ll # CYRILLIC SMALL LETTER YERU WITH DIAERESIS +04FB ; Ll # CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK +04FD ; Ll # CYRILLIC SMALL LETTER HA WITH HOOK +04FF ; Ll # CYRILLIC SMALL LETTER HA WITH STROKE +0501 ; Ll # CYRILLIC SMALL LETTER KOMI DE +0503 ; Ll # CYRILLIC SMALL LETTER KOMI DJE +0505 ; Ll # CYRILLIC SMALL LETTER KOMI ZJE +0507 ; Ll # CYRILLIC SMALL LETTER KOMI DZJE +0509 ; Ll # CYRILLIC SMALL LETTER KOMI LJE +050B ; Ll # CYRILLIC SMALL LETTER KOMI NJE +050D ; Ll # CYRILLIC SMALL LETTER KOMI SJE +050F ; Ll # CYRILLIC SMALL LETTER KOMI TJE +0511 ; Ll # CYRILLIC SMALL LETTER REVERSED ZE +0513 ; Ll # CYRILLIC SMALL LETTER EL WITH HOOK +0515 ; Ll # CYRILLIC SMALL LETTER LHA +0517 ; Ll # CYRILLIC SMALL LETTER RHA +0519 ; Ll # CYRILLIC SMALL LETTER YAE +051B ; Ll # CYRILLIC SMALL LETTER QA +051D ; Ll # CYRILLIC SMALL LETTER WE +051F ; Ll # CYRILLIC SMALL LETTER ALEUT KA +0521 ; Ll # CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK +0523 ; Ll # CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK +0525 ; Ll # CYRILLIC SMALL LETTER PE WITH DESCENDER +0527 ; Ll # CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0529 ; Ll # CYRILLIC SMALL LETTER EN WITH LEFT HOOK +052B ; Ll # CYRILLIC SMALL LETTER DZZHE +052D ; Ll # CYRILLIC SMALL LETTER DCHE +052F ; Ll # CYRILLIC SMALL LETTER EL WITH DESCENDER +0561..0587 ; Ll # [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN +13F8..13FD ; Ll # [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV +1C80..1C88 ; Ll # [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1D00..1D2B ; Ll # [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL +1D6B..1D77 ; Ll # [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G +1D79..1D9A ; Ll # [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +1E01 ; Ll # LATIN SMALL LETTER A WITH RING BELOW +1E03 ; Ll # LATIN SMALL LETTER B WITH DOT ABOVE +1E05 ; Ll # LATIN SMALL LETTER B WITH DOT BELOW +1E07 ; Ll # LATIN SMALL LETTER B WITH LINE BELOW +1E09 ; Ll # LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +1E0B ; Ll # LATIN SMALL LETTER D WITH DOT ABOVE +1E0D ; Ll # LATIN SMALL LETTER D WITH DOT BELOW +1E0F ; Ll # LATIN SMALL LETTER D WITH LINE BELOW +1E11 ; Ll # LATIN SMALL LETTER D WITH CEDILLA +1E13 ; Ll # LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +1E15 ; Ll # LATIN SMALL LETTER E WITH MACRON AND GRAVE +1E17 ; Ll # LATIN SMALL LETTER E WITH MACRON AND ACUTE +1E19 ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +1E1B ; Ll # LATIN SMALL LETTER E WITH TILDE BELOW +1E1D ; Ll # LATIN SMALL LETTER E WITH CEDILLA AND BREVE +1E1F ; Ll # LATIN SMALL LETTER F WITH DOT ABOVE +1E21 ; Ll # LATIN SMALL LETTER G WITH MACRON +1E23 ; Ll # LATIN SMALL LETTER H WITH DOT ABOVE +1E25 ; Ll # LATIN SMALL LETTER H WITH DOT BELOW +1E27 ; Ll # LATIN SMALL LETTER H WITH DIAERESIS +1E29 ; Ll # LATIN SMALL LETTER H WITH CEDILLA +1E2B ; Ll # LATIN SMALL LETTER H WITH BREVE BELOW +1E2D ; Ll # LATIN SMALL LETTER I WITH TILDE BELOW +1E2F ; Ll # LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +1E31 ; Ll # LATIN SMALL LETTER K WITH ACUTE +1E33 ; Ll # LATIN SMALL LETTER K WITH DOT BELOW +1E35 ; Ll # LATIN SMALL LETTER K WITH LINE BELOW +1E37 ; Ll # LATIN SMALL LETTER L WITH DOT BELOW +1E39 ; Ll # LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +1E3B ; Ll # LATIN SMALL LETTER L WITH LINE BELOW +1E3D ; Ll # LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +1E3F ; Ll # LATIN SMALL LETTER M WITH ACUTE +1E41 ; Ll # LATIN SMALL LETTER M WITH DOT ABOVE +1E43 ; Ll # LATIN SMALL LETTER M WITH DOT BELOW +1E45 ; Ll # LATIN SMALL LETTER N WITH DOT ABOVE +1E47 ; Ll # LATIN SMALL LETTER N WITH DOT BELOW +1E49 ; Ll # LATIN SMALL LETTER N WITH LINE BELOW +1E4B ; Ll # LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +1E4D ; Ll # LATIN SMALL LETTER O WITH TILDE AND ACUTE +1E4F ; Ll # LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +1E51 ; Ll # LATIN SMALL LETTER O WITH MACRON AND GRAVE +1E53 ; Ll # LATIN SMALL LETTER O WITH MACRON AND ACUTE +1E55 ; Ll # LATIN SMALL LETTER P WITH ACUTE +1E57 ; Ll # LATIN SMALL LETTER P WITH DOT ABOVE +1E59 ; Ll # LATIN SMALL LETTER R WITH DOT ABOVE +1E5B ; Ll # LATIN SMALL LETTER R WITH DOT BELOW +1E5D ; Ll # LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +1E5F ; Ll # LATIN SMALL LETTER R WITH LINE BELOW +1E61 ; Ll # LATIN SMALL LETTER S WITH DOT ABOVE +1E63 ; Ll # LATIN SMALL LETTER S WITH DOT BELOW +1E65 ; Ll # LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +1E67 ; Ll # LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +1E69 ; Ll # LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +1E6B ; Ll # LATIN SMALL LETTER T WITH DOT ABOVE +1E6D ; Ll # LATIN SMALL LETTER T WITH DOT BELOW +1E6F ; Ll # LATIN SMALL LETTER T WITH LINE BELOW +1E71 ; Ll # LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +1E73 ; Ll # LATIN SMALL LETTER U WITH DIAERESIS BELOW +1E75 ; Ll # LATIN SMALL LETTER U WITH TILDE BELOW +1E77 ; Ll # LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +1E79 ; Ll # LATIN SMALL LETTER U WITH TILDE AND ACUTE +1E7B ; Ll # LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +1E7D ; Ll # LATIN SMALL LETTER V WITH TILDE +1E7F ; Ll # LATIN SMALL LETTER V WITH DOT BELOW +1E81 ; Ll # LATIN SMALL LETTER W WITH GRAVE +1E83 ; Ll # LATIN SMALL LETTER W WITH ACUTE +1E85 ; Ll # LATIN SMALL LETTER W WITH DIAERESIS +1E87 ; Ll # LATIN SMALL LETTER W WITH DOT ABOVE +1E89 ; Ll # LATIN SMALL LETTER W WITH DOT BELOW +1E8B ; Ll # LATIN SMALL LETTER X WITH DOT ABOVE +1E8D ; Ll # LATIN SMALL LETTER X WITH DIAERESIS +1E8F ; Ll # LATIN SMALL LETTER Y WITH DOT ABOVE +1E91 ; Ll # LATIN SMALL LETTER Z WITH CIRCUMFLEX +1E93 ; Ll # LATIN SMALL LETTER Z WITH DOT BELOW +1E95..1E9D ; Ll # [9] LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER LONG S WITH HIGH STROKE +1E9F ; Ll # LATIN SMALL LETTER DELTA +1EA1 ; Ll # LATIN SMALL LETTER A WITH DOT BELOW +1EA3 ; Ll # LATIN SMALL LETTER A WITH HOOK ABOVE +1EA5 ; Ll # LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA7 ; Ll # LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA9 ; Ll # LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EAB ; Ll # LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +1EAD ; Ll # LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAF ; Ll # LATIN SMALL LETTER A WITH BREVE AND ACUTE +1EB1 ; Ll # LATIN SMALL LETTER A WITH BREVE AND GRAVE +1EB3 ; Ll # LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +1EB5 ; Ll # LATIN SMALL LETTER A WITH BREVE AND TILDE +1EB7 ; Ll # LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +1EB9 ; Ll # LATIN SMALL LETTER E WITH DOT BELOW +1EBB ; Ll # LATIN SMALL LETTER E WITH HOOK ABOVE +1EBD ; Ll # LATIN SMALL LETTER E WITH TILDE +1EBF ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC1 ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC3 ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC5 ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +1EC7 ; Ll # LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC9 ; Ll # LATIN SMALL LETTER I WITH HOOK ABOVE +1ECB ; Ll # LATIN SMALL LETTER I WITH DOT BELOW +1ECD ; Ll # LATIN SMALL LETTER O WITH DOT BELOW +1ECF ; Ll # LATIN SMALL LETTER O WITH HOOK ABOVE +1ED1 ; Ll # LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED3 ; Ll # LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED5 ; Ll # LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED7 ; Ll # LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +1ED9 ; Ll # LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1EDB ; Ll # LATIN SMALL LETTER O WITH HORN AND ACUTE +1EDD ; Ll # LATIN SMALL LETTER O WITH HORN AND GRAVE +1EDF ; Ll # LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +1EE1 ; Ll # LATIN SMALL LETTER O WITH HORN AND TILDE +1EE3 ; Ll # LATIN SMALL LETTER O WITH HORN AND DOT BELOW +1EE5 ; Ll # LATIN SMALL LETTER U WITH DOT BELOW +1EE7 ; Ll # LATIN SMALL LETTER U WITH HOOK ABOVE +1EE9 ; Ll # LATIN SMALL LETTER U WITH HORN AND ACUTE +1EEB ; Ll # LATIN SMALL LETTER U WITH HORN AND GRAVE +1EED ; Ll # LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +1EEF ; Ll # LATIN SMALL LETTER U WITH HORN AND TILDE +1EF1 ; Ll # LATIN SMALL LETTER U WITH HORN AND DOT BELOW +1EF3 ; Ll # LATIN SMALL LETTER Y WITH GRAVE +1EF5 ; Ll # LATIN SMALL LETTER Y WITH DOT BELOW +1EF7 ; Ll # LATIN SMALL LETTER Y WITH HOOK ABOVE +1EF9 ; Ll # LATIN SMALL LETTER Y WITH TILDE +1EFB ; Ll # LATIN SMALL LETTER MIDDLE-WELSH LL +1EFD ; Ll # LATIN SMALL LETTER MIDDLE-WELSH V +1EFF..1F07 ; Ll # [9] LATIN SMALL LETTER Y WITH LOOP..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F10..1F15 ; Ll # [6] GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F20..1F27 ; Ll # [8] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI +1F30..1F37 ; Ll # [8] GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI +1F40..1F45 ; Ll # [6] GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F50..1F57 ; Ll # [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F60..1F67 ; Ll # [8] GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F70..1F7D ; Ll # [14] GREEK SMALL LETTER ALPHA WITH VARIA..GREEK SMALL LETTER OMEGA WITH OXIA +1F80..1F87 ; Ll # [8] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F90..1F97 ; Ll # [8] GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FA0..1FA7 ; Ll # [8] GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FB0..1FB4 ; Ll # [5] GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1FB6..1FB7 ; Ll # [2] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FBE ; Ll # GREEK PROSGEGRAMMENI +1FC2..1FC4 ; Ll # [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1FC6..1FC7 ; Ll # [2] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FD0..1FD3 ; Ll # [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD6..1FD7 ; Ll # [2] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FE0..1FE7 ; Ll # [8] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FF2..1FF4 ; Ll # [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1FF6..1FF7 ; Ll # [2] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +210A ; Ll # SCRIPT SMALL G +210E..210F ; Ll # [2] PLANCK CONSTANT..PLANCK CONSTANT OVER TWO PI +2113 ; Ll # SCRIPT SMALL L +212F ; Ll # SCRIPT SMALL E +2134 ; Ll # SCRIPT SMALL O +2139 ; Ll # INFORMATION SOURCE +213C..213D ; Ll # [2] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK SMALL GAMMA +2146..2149 ; Ll # [4] DOUBLE-STRUCK ITALIC SMALL D..DOUBLE-STRUCK ITALIC SMALL J +214E ; Ll # TURNED SMALL F +2184 ; Ll # LATIN SMALL LETTER REVERSED C +2C30..2C5E ; Ll # [47] GLAGOLITIC SMALL LETTER AZU..GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C61 ; Ll # LATIN SMALL LETTER L WITH DOUBLE BAR +2C65..2C66 ; Ll # [2] LATIN SMALL LETTER A WITH STROKE..LATIN SMALL LETTER T WITH DIAGONAL STROKE +2C68 ; Ll # LATIN SMALL LETTER H WITH DESCENDER +2C6A ; Ll # LATIN SMALL LETTER K WITH DESCENDER +2C6C ; Ll # LATIN SMALL LETTER Z WITH DESCENDER +2C71 ; Ll # LATIN SMALL LETTER V WITH RIGHT HOOK +2C73..2C74 ; Ll # [2] LATIN SMALL LETTER W WITH HOOK..LATIN SMALL LETTER V WITH CURL +2C76..2C7B ; Ll # [6] LATIN SMALL LETTER HALF H..LATIN LETTER SMALL CAPITAL TURNED E +2C81 ; Ll # COPTIC SMALL LETTER ALFA +2C83 ; Ll # COPTIC SMALL LETTER VIDA +2C85 ; Ll # COPTIC SMALL LETTER GAMMA +2C87 ; Ll # COPTIC SMALL LETTER DALDA +2C89 ; Ll # COPTIC SMALL LETTER EIE +2C8B ; Ll # COPTIC SMALL LETTER SOU +2C8D ; Ll # COPTIC SMALL LETTER ZATA +2C8F ; Ll # COPTIC SMALL LETTER HATE +2C91 ; Ll # COPTIC SMALL LETTER THETHE +2C93 ; Ll # COPTIC SMALL LETTER IAUDA +2C95 ; Ll # COPTIC SMALL LETTER KAPA +2C97 ; Ll # COPTIC SMALL LETTER LAULA +2C99 ; Ll # COPTIC SMALL LETTER MI +2C9B ; Ll # COPTIC SMALL LETTER NI +2C9D ; Ll # COPTIC SMALL LETTER KSI +2C9F ; Ll # COPTIC SMALL LETTER O +2CA1 ; Ll # COPTIC SMALL LETTER PI +2CA3 ; Ll # COPTIC SMALL LETTER RO +2CA5 ; Ll # COPTIC SMALL LETTER SIMA +2CA7 ; Ll # COPTIC SMALL LETTER TAU +2CA9 ; Ll # COPTIC SMALL LETTER UA +2CAB ; Ll # COPTIC SMALL LETTER FI +2CAD ; Ll # COPTIC SMALL LETTER KHI +2CAF ; Ll # COPTIC SMALL LETTER PSI +2CB1 ; Ll # COPTIC SMALL LETTER OOU +2CB3 ; Ll # COPTIC SMALL LETTER DIALECT-P ALEF +2CB5 ; Ll # COPTIC SMALL LETTER OLD COPTIC AIN +2CB7 ; Ll # COPTIC SMALL LETTER CRYPTOGRAMMIC EIE +2CB9 ; Ll # COPTIC SMALL LETTER DIALECT-P KAPA +2CBB ; Ll # COPTIC SMALL LETTER DIALECT-P NI +2CBD ; Ll # COPTIC SMALL LETTER CRYPTOGRAMMIC NI +2CBF ; Ll # COPTIC SMALL LETTER OLD COPTIC OOU +2CC1 ; Ll # COPTIC SMALL LETTER SAMPI +2CC3 ; Ll # COPTIC SMALL LETTER CROSSED SHEI +2CC5 ; Ll # COPTIC SMALL LETTER OLD COPTIC SHEI +2CC7 ; Ll # COPTIC SMALL LETTER OLD COPTIC ESH +2CC9 ; Ll # COPTIC SMALL LETTER AKHMIMIC KHEI +2CCB ; Ll # COPTIC SMALL LETTER DIALECT-P HORI +2CCD ; Ll # COPTIC SMALL LETTER OLD COPTIC HORI +2CCF ; Ll # COPTIC SMALL LETTER OLD COPTIC HA +2CD1 ; Ll # COPTIC SMALL LETTER L-SHAPED HA +2CD3 ; Ll # COPTIC SMALL LETTER OLD COPTIC HEI +2CD5 ; Ll # COPTIC SMALL LETTER OLD COPTIC HAT +2CD7 ; Ll # COPTIC SMALL LETTER OLD COPTIC GANGIA +2CD9 ; Ll # COPTIC SMALL LETTER OLD COPTIC DJA +2CDB ; Ll # COPTIC SMALL LETTER OLD COPTIC SHIMA +2CDD ; Ll # COPTIC SMALL LETTER OLD NUBIAN SHIMA +2CDF ; Ll # COPTIC SMALL LETTER OLD NUBIAN NGI +2CE1 ; Ll # COPTIC SMALL LETTER OLD NUBIAN NYI +2CE3..2CE4 ; Ll # [2] COPTIC SMALL LETTER OLD NUBIAN WAU..COPTIC SYMBOL KAI +2CEC ; Ll # COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI +2CEE ; Ll # COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2CF3 ; Ll # COPTIC SMALL LETTER BOHAIRIC KHEI +2D00..2D25 ; Ll # [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE +2D27 ; Ll # GEORGIAN SMALL LETTER YN +2D2D ; Ll # GEORGIAN SMALL LETTER AEN +A641 ; Ll # CYRILLIC SMALL LETTER ZEMLYA +A643 ; Ll # CYRILLIC SMALL LETTER DZELO +A645 ; Ll # CYRILLIC SMALL LETTER REVERSED DZE +A647 ; Ll # CYRILLIC SMALL LETTER IOTA +A649 ; Ll # CYRILLIC SMALL LETTER DJERV +A64B ; Ll # CYRILLIC SMALL LETTER MONOGRAPH UK +A64D ; Ll # CYRILLIC SMALL LETTER BROAD OMEGA +A64F ; Ll # CYRILLIC SMALL LETTER NEUTRAL YER +A651 ; Ll # CYRILLIC SMALL LETTER YERU WITH BACK YER +A653 ; Ll # CYRILLIC SMALL LETTER IOTIFIED YAT +A655 ; Ll # CYRILLIC SMALL LETTER REVERSED YU +A657 ; Ll # CYRILLIC SMALL LETTER IOTIFIED A +A659 ; Ll # CYRILLIC SMALL LETTER CLOSED LITTLE YUS +A65B ; Ll # CYRILLIC SMALL LETTER BLENDED YUS +A65D ; Ll # CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS +A65F ; Ll # CYRILLIC SMALL LETTER YN +A661 ; Ll # CYRILLIC SMALL LETTER REVERSED TSE +A663 ; Ll # CYRILLIC SMALL LETTER SOFT DE +A665 ; Ll # CYRILLIC SMALL LETTER SOFT EL +A667 ; Ll # CYRILLIC SMALL LETTER SOFT EM +A669 ; Ll # CYRILLIC SMALL LETTER MONOCULAR O +A66B ; Ll # CYRILLIC SMALL LETTER BINOCULAR O +A66D ; Ll # CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A681 ; Ll # CYRILLIC SMALL LETTER DWE +A683 ; Ll # CYRILLIC SMALL LETTER DZWE +A685 ; Ll # CYRILLIC SMALL LETTER ZHWE +A687 ; Ll # CYRILLIC SMALL LETTER CCHE +A689 ; Ll # CYRILLIC SMALL LETTER DZZE +A68B ; Ll # CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK +A68D ; Ll # CYRILLIC SMALL LETTER TWE +A68F ; Ll # CYRILLIC SMALL LETTER TSWE +A691 ; Ll # CYRILLIC SMALL LETTER TSSE +A693 ; Ll # CYRILLIC SMALL LETTER TCHE +A695 ; Ll # CYRILLIC SMALL LETTER HWE +A697 ; Ll # CYRILLIC SMALL LETTER SHWE +A699 ; Ll # CYRILLIC SMALL LETTER DOUBLE O +A69B ; Ll # CYRILLIC SMALL LETTER CROSSED O +A723 ; Ll # LATIN SMALL LETTER EGYPTOLOGICAL ALEF +A725 ; Ll # LATIN SMALL LETTER EGYPTOLOGICAL AIN +A727 ; Ll # LATIN SMALL LETTER HENG +A729 ; Ll # LATIN SMALL LETTER TZ +A72B ; Ll # LATIN SMALL LETTER TRESILLO +A72D ; Ll # LATIN SMALL LETTER CUATRILLO +A72F..A731 ; Ll # [3] LATIN SMALL LETTER CUATRILLO WITH COMMA..LATIN LETTER SMALL CAPITAL S +A733 ; Ll # LATIN SMALL LETTER AA +A735 ; Ll # LATIN SMALL LETTER AO +A737 ; Ll # LATIN SMALL LETTER AU +A739 ; Ll # LATIN SMALL LETTER AV +A73B ; Ll # LATIN SMALL LETTER AV WITH HORIZONTAL BAR +A73D ; Ll # LATIN SMALL LETTER AY +A73F ; Ll # LATIN SMALL LETTER REVERSED C WITH DOT +A741 ; Ll # LATIN SMALL LETTER K WITH STROKE +A743 ; Ll # LATIN SMALL LETTER K WITH DIAGONAL STROKE +A745 ; Ll # LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE +A747 ; Ll # LATIN SMALL LETTER BROKEN L +A749 ; Ll # LATIN SMALL LETTER L WITH HIGH STROKE +A74B ; Ll # LATIN SMALL LETTER O WITH LONG STROKE OVERLAY +A74D ; Ll # LATIN SMALL LETTER O WITH LOOP +A74F ; Ll # LATIN SMALL LETTER OO +A751 ; Ll # LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER +A753 ; Ll # LATIN SMALL LETTER P WITH FLOURISH +A755 ; Ll # LATIN SMALL LETTER P WITH SQUIRREL TAIL +A757 ; Ll # LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER +A759 ; Ll # LATIN SMALL LETTER Q WITH DIAGONAL STROKE +A75B ; Ll # LATIN SMALL LETTER R ROTUNDA +A75D ; Ll # LATIN SMALL LETTER RUM ROTUNDA +A75F ; Ll # LATIN SMALL LETTER V WITH DIAGONAL STROKE +A761 ; Ll # LATIN SMALL LETTER VY +A763 ; Ll # LATIN SMALL LETTER VISIGOTHIC Z +A765 ; Ll # LATIN SMALL LETTER THORN WITH STROKE +A767 ; Ll # LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER +A769 ; Ll # LATIN SMALL LETTER VEND +A76B ; Ll # LATIN SMALL LETTER ET +A76D ; Ll # LATIN SMALL LETTER IS +A76F ; Ll # LATIN SMALL LETTER CON +A771..A778 ; Ll # [8] LATIN SMALL LETTER DUM..LATIN SMALL LETTER UM +A77A ; Ll # LATIN SMALL LETTER INSULAR D +A77C ; Ll # LATIN SMALL LETTER INSULAR F +A77F ; Ll # LATIN SMALL LETTER TURNED INSULAR G +A781 ; Ll # LATIN SMALL LETTER TURNED L +A783 ; Ll # LATIN SMALL LETTER INSULAR R +A785 ; Ll # LATIN SMALL LETTER INSULAR S +A787 ; Ll # LATIN SMALL LETTER INSULAR T +A78C ; Ll # LATIN SMALL LETTER SALTILLO +A78E ; Ll # LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +A791 ; Ll # LATIN SMALL LETTER N WITH DESCENDER +A793..A795 ; Ll # [3] LATIN SMALL LETTER C WITH BAR..LATIN SMALL LETTER H WITH PALATAL HOOK +A797 ; Ll # LATIN SMALL LETTER B WITH FLOURISH +A799 ; Ll # LATIN SMALL LETTER F WITH STROKE +A79B ; Ll # LATIN SMALL LETTER VOLAPUK AE +A79D ; Ll # LATIN SMALL LETTER VOLAPUK OE +A79F ; Ll # LATIN SMALL LETTER VOLAPUK UE +A7A1 ; Ll # LATIN SMALL LETTER G WITH OBLIQUE STROKE +A7A3 ; Ll # LATIN SMALL LETTER K WITH OBLIQUE STROKE +A7A5 ; Ll # LATIN SMALL LETTER N WITH OBLIQUE STROKE +A7A7 ; Ll # LATIN SMALL LETTER R WITH OBLIQUE STROKE +A7A9 ; Ll # LATIN SMALL LETTER S WITH OBLIQUE STROKE +A7B5 ; Ll # LATIN SMALL LETTER BETA +A7B7 ; Ll # LATIN SMALL LETTER OMEGA +A7FA ; Ll # LATIN LETTER SMALL CAPITAL TURNED M +AB30..AB5A ; Ll # [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG +AB60..AB65 ; Ll # [6] LATIN SMALL LETTER SAKHA YAT..GREEK LETTER SMALL CAPITAL OMEGA +AB70..ABBF ; Ll # [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA +FB00..FB06 ; Ll # [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST +FB13..FB17 ; Ll # [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH +FF41..FF5A ; Ll # [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z +10428..1044F ; Ll # [40] DESERET SMALL LETTER LONG I..DESERET SMALL LETTER EW +104D8..104FB ; Ll # [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA +10CC0..10CF2 ; Ll # [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +118C0..118DF ; Ll # [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO +1D41A..1D433 ; Ll # [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z +1D44E..1D454 ; Ll # [7] MATHEMATICAL ITALIC SMALL A..MATHEMATICAL ITALIC SMALL G +1D456..1D467 ; Ll # [18] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL ITALIC SMALL Z +1D482..1D49B ; Ll # [26] MATHEMATICAL BOLD ITALIC SMALL A..MATHEMATICAL BOLD ITALIC SMALL Z +1D4B6..1D4B9 ; Ll # [4] MATHEMATICAL SCRIPT SMALL A..MATHEMATICAL SCRIPT SMALL D +1D4BB ; Ll # MATHEMATICAL SCRIPT SMALL F +1D4BD..1D4C3 ; Ll # [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N +1D4C5..1D4CF ; Ll # [11] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL SCRIPT SMALL Z +1D4EA..1D503 ; Ll # [26] MATHEMATICAL BOLD SCRIPT SMALL A..MATHEMATICAL BOLD SCRIPT SMALL Z +1D51E..1D537 ; Ll # [26] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL FRAKTUR SMALL Z +1D552..1D56B ; Ll # [26] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL DOUBLE-STRUCK SMALL Z +1D586..1D59F ; Ll # [26] MATHEMATICAL BOLD FRAKTUR SMALL A..MATHEMATICAL BOLD FRAKTUR SMALL Z +1D5BA..1D5D3 ; Ll # [26] MATHEMATICAL SANS-SERIF SMALL A..MATHEMATICAL SANS-SERIF SMALL Z +1D5EE..1D607 ; Ll # [26] MATHEMATICAL SANS-SERIF BOLD SMALL A..MATHEMATICAL SANS-SERIF BOLD SMALL Z +1D622..1D63B ; Ll # [26] MATHEMATICAL SANS-SERIF ITALIC SMALL A..MATHEMATICAL SANS-SERIF ITALIC SMALL Z +1D656..1D66F ; Ll # [26] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z +1D68A..1D6A5 ; Ll # [28] MATHEMATICAL MONOSPACE SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J +1D6C2..1D6DA ; Ll # [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA +1D6DC..1D6E1 ; Ll # [6] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL BOLD PI SYMBOL +1D6FC..1D714 ; Ll # [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA +1D716..1D71B ; Ll # [6] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL ITALIC PI SYMBOL +1D736..1D74E ; Ll # [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D750..1D755 ; Ll # [6] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC PI SYMBOL +1D770..1D788 ; Ll # [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D78A..1D78F ; Ll # [6] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD PI SYMBOL +1D7AA..1D7C2 ; Ll # [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C4..1D7C9 ; Ll # [6] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL +1D7CB ; Ll # MATHEMATICAL BOLD SMALL DIGAMMA +1E922..1E943 ; Ll # [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA + +# Total code points: 2063 + +# ================================================ + +# General_Category=Titlecase_Letter + +01C5 ; Lt # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C8 ; Lt # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01CB ; Lt # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01F2 ; Lt # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +1F88..1F8F ; Lt # [8] GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F98..1F9F ; Lt # [8] GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA8..1FAF ; Lt # [8] GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI..GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FBC ; Lt # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +1FCC ; Lt # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +1FFC ; Lt # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + +# Total code points: 31 + +# ================================================ + +# General_Category=Modifier_Letter + +02B0..02C1 ; Lm # [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP +02C6..02D1 ; Lm # [12] MODIFIER LETTER CIRCUMFLEX ACCENT..MODIFIER LETTER HALF TRIANGULAR COLON +02E0..02E4 ; Lm # [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02EC ; Lm # MODIFIER LETTER VOICING +02EE ; Lm # MODIFIER LETTER DOUBLE APOSTROPHE +0374 ; Lm # GREEK NUMERAL SIGN +037A ; Lm # GREEK YPOGEGRAMMENI +0559 ; Lm # ARMENIAN MODIFIER LETTER LEFT HALF RING +0640 ; Lm # ARABIC TATWEEL +06E5..06E6 ; Lm # [2] ARABIC SMALL WAW..ARABIC SMALL YEH +07F4..07F5 ; Lm # [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE +07FA ; Lm # NKO LAJANYALAN +081A ; Lm # SAMARITAN MODIFIER LETTER EPENTHETIC YUT +0824 ; Lm # SAMARITAN MODIFIER LETTER SHORT A +0828 ; Lm # SAMARITAN MODIFIER LETTER I +0971 ; Lm # DEVANAGARI SIGN HIGH SPACING DOT +0E46 ; Lm # THAI CHARACTER MAIYAMOK +0EC6 ; Lm # LAO KO LA +10FC ; Lm # MODIFIER LETTER GEORGIAN NAR +17D7 ; Lm # KHMER SIGN LEK TOO +1843 ; Lm # MONGOLIAN LETTER TODO LONG VOWEL SIGN +1AA7 ; Lm # TAI THAM SIGN MAI YAMOK +1C78..1C7D ; Lm # [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD +1D2C..1D6A ; Lm # [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI +1D78 ; Lm # MODIFIER LETTER CYRILLIC EN +1D9B..1DBF ; Lm # [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA +2071 ; Lm # SUPERSCRIPT LATIN SMALL LETTER I +207F ; Lm # SUPERSCRIPT LATIN SMALL LETTER N +2090..209C ; Lm # [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T +2C7C..2C7D ; Lm # [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V +2D6F ; Lm # TIFINAGH MODIFIER LETTER LABIALIZATION MARK +2E2F ; Lm # VERTICAL TILDE +3005 ; Lm # IDEOGRAPHIC ITERATION MARK +3031..3035 ; Lm # [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF +303B ; Lm # VERTICAL IDEOGRAPHIC ITERATION MARK +309D..309E ; Lm # [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK +30FC..30FE ; Lm # [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK +A015 ; Lm # YI SYLLABLE WU +A4F8..A4FD ; Lm # [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU +A60C ; Lm # VAI SYLLABLE LENGTHENER +A67F ; Lm # CYRILLIC PAYEROK +A69C..A69D ; Lm # [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN +A717..A71F ; Lm # [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK +A770 ; Lm # MODIFIER LETTER US +A788 ; Lm # MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A7F8..A7F9 ; Lm # [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE +A9CF ; Lm # JAVANESE PANGRANGKEP +A9E6 ; Lm # MYANMAR MODIFIER LETTER SHAN REDUPLICATION +AA70 ; Lm # MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION +AADD ; Lm # TAI VIET SYMBOL SAM +AAF3..AAF4 ; Lm # [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK +AB5C..AB5F ; Lm # [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK +FF70 ; Lm # HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF9E..FF9F ; Lm # [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +16B40..16B43 ; Lm # [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM +16F93..16F9F ; Lm # [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 +16FE0 ; Lm # TANGUT ITERATION MARK + +# Total code points: 249 + +# ================================================ + +# General_Category=Other_Letter + +00AA ; Lo # FEMININE ORDINAL INDICATOR +00BA ; Lo # MASCULINE ORDINAL INDICATOR +01BB ; Lo # LATIN LETTER TWO WITH STROKE +01C0..01C3 ; Lo # [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK +0294 ; Lo # LATIN LETTER GLOTTAL STOP +05D0..05EA ; Lo # [27] HEBREW LETTER ALEF..HEBREW LETTER TAV +05F0..05F2 ; Lo # [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD +0620..063F ; Lo # [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0641..064A ; Lo # [10] ARABIC LETTER FEH..ARABIC LETTER YEH +066E..066F ; Lo # [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF +0671..06D3 ; Lo # [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +06D5 ; Lo # ARABIC LETTER AE +06EE..06EF ; Lo # [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V +06FA..06FC ; Lo # [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW +06FF ; Lo # ARABIC LETTER HEH WITH INVERTED V +0710 ; Lo # SYRIAC LETTER ALAPH +0712..072F ; Lo # [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH +074D..07A5 ; Lo # [89] SYRIAC LETTER SOGDIAN ZHAIN..THAANA LETTER WAAVU +07B1 ; Lo # THAANA LETTER NAA +07CA..07EA ; Lo # [33] NKO LETTER A..NKO LETTER JONA RA +0800..0815 ; Lo # [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF +0840..0858 ; Lo # [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN +08A0..08B4 ; Lo # [21] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER KAF WITH DOT BELOW +08B6..08BD ; Lo # [8] ARABIC LETTER BEH WITH SMALL MEEM ABOVE..ARABIC LETTER AFRICAN NOON +0904..0939 ; Lo # [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA +093D ; Lo # DEVANAGARI SIGN AVAGRAHA +0950 ; Lo # DEVANAGARI OM +0958..0961 ; Lo # [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL +0972..0980 ; Lo # [15] DEVANAGARI LETTER CANDRA A..BENGALI ANJI +0985..098C ; Lo # [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L +098F..0990 ; Lo # [2] BENGALI LETTER E..BENGALI LETTER AI +0993..09A8 ; Lo # [22] BENGALI LETTER O..BENGALI LETTER NA +09AA..09B0 ; Lo # [7] BENGALI LETTER PA..BENGALI LETTER RA +09B2 ; Lo # BENGALI LETTER LA +09B6..09B9 ; Lo # [4] BENGALI LETTER SHA..BENGALI LETTER HA +09BD ; Lo # BENGALI SIGN AVAGRAHA +09CE ; Lo # BENGALI LETTER KHANDA TA +09DC..09DD ; Lo # [2] BENGALI LETTER RRA..BENGALI LETTER RHA +09DF..09E1 ; Lo # [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL +09F0..09F1 ; Lo # [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL +0A05..0A0A ; Lo # [6] GURMUKHI LETTER A..GURMUKHI LETTER UU +0A0F..0A10 ; Lo # [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI +0A13..0A28 ; Lo # [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA +0A2A..0A30 ; Lo # [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA +0A32..0A33 ; Lo # [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA +0A35..0A36 ; Lo # [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA +0A38..0A39 ; Lo # [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA +0A59..0A5C ; Lo # [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA +0A5E ; Lo # GURMUKHI LETTER FA +0A72..0A74 ; Lo # [3] GURMUKHI IRI..GURMUKHI EK ONKAR +0A85..0A8D ; Lo # [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E +0A8F..0A91 ; Lo # [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O +0A93..0AA8 ; Lo # [22] GUJARATI LETTER O..GUJARATI LETTER NA +0AAA..0AB0 ; Lo # [7] GUJARATI LETTER PA..GUJARATI LETTER RA +0AB2..0AB3 ; Lo # [2] GUJARATI LETTER LA..GUJARATI LETTER LLA +0AB5..0AB9 ; Lo # [5] GUJARATI LETTER VA..GUJARATI LETTER HA +0ABD ; Lo # GUJARATI SIGN AVAGRAHA +0AD0 ; Lo # GUJARATI OM +0AE0..0AE1 ; Lo # [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL +0AF9 ; Lo # GUJARATI LETTER ZHA +0B05..0B0C ; Lo # [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L +0B0F..0B10 ; Lo # [2] ORIYA LETTER E..ORIYA LETTER AI +0B13..0B28 ; Lo # [22] ORIYA LETTER O..ORIYA LETTER NA +0B2A..0B30 ; Lo # [7] ORIYA LETTER PA..ORIYA LETTER RA +0B32..0B33 ; Lo # [2] ORIYA LETTER LA..ORIYA LETTER LLA +0B35..0B39 ; Lo # [5] ORIYA LETTER VA..ORIYA LETTER HA +0B3D ; Lo # ORIYA SIGN AVAGRAHA +0B5C..0B5D ; Lo # [2] ORIYA LETTER RRA..ORIYA LETTER RHA +0B5F..0B61 ; Lo # [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL +0B71 ; Lo # ORIYA LETTER WA +0B83 ; Lo # TAMIL SIGN VISARGA +0B85..0B8A ; Lo # [6] TAMIL LETTER A..TAMIL LETTER UU +0B8E..0B90 ; Lo # [3] TAMIL LETTER E..TAMIL LETTER AI +0B92..0B95 ; Lo # [4] TAMIL LETTER O..TAMIL LETTER KA +0B99..0B9A ; Lo # [2] TAMIL LETTER NGA..TAMIL LETTER CA +0B9C ; Lo # TAMIL LETTER JA +0B9E..0B9F ; Lo # [2] TAMIL LETTER NYA..TAMIL LETTER TTA +0BA3..0BA4 ; Lo # [2] TAMIL LETTER NNA..TAMIL LETTER TA +0BA8..0BAA ; Lo # [3] TAMIL LETTER NA..TAMIL LETTER PA +0BAE..0BB9 ; Lo # [12] TAMIL LETTER MA..TAMIL LETTER HA +0BD0 ; Lo # TAMIL OM +0C05..0C0C ; Lo # [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L +0C0E..0C10 ; Lo # [3] TELUGU LETTER E..TELUGU LETTER AI +0C12..0C28 ; Lo # [23] TELUGU LETTER O..TELUGU LETTER NA +0C2A..0C39 ; Lo # [16] TELUGU LETTER PA..TELUGU LETTER HA +0C3D ; Lo # TELUGU SIGN AVAGRAHA +0C58..0C5A ; Lo # [3] TELUGU LETTER TSA..TELUGU LETTER RRRA +0C60..0C61 ; Lo # [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL +0C80 ; Lo # KANNADA SIGN SPACING CANDRABINDU +0C85..0C8C ; Lo # [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L +0C8E..0C90 ; Lo # [3] KANNADA LETTER E..KANNADA LETTER AI +0C92..0CA8 ; Lo # [23] KANNADA LETTER O..KANNADA LETTER NA +0CAA..0CB3 ; Lo # [10] KANNADA LETTER PA..KANNADA LETTER LLA +0CB5..0CB9 ; Lo # [5] KANNADA LETTER VA..KANNADA LETTER HA +0CBD ; Lo # KANNADA SIGN AVAGRAHA +0CDE ; Lo # KANNADA LETTER FA +0CE0..0CE1 ; Lo # [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL +0CF1..0CF2 ; Lo # [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA +0D05..0D0C ; Lo # [8] MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L +0D0E..0D10 ; Lo # [3] MALAYALAM LETTER E..MALAYALAM LETTER AI +0D12..0D3A ; Lo # [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA +0D3D ; Lo # MALAYALAM SIGN AVAGRAHA +0D4E ; Lo # MALAYALAM LETTER DOT REPH +0D54..0D56 ; Lo # [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL +0D5F..0D61 ; Lo # [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL +0D7A..0D7F ; Lo # [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K +0D85..0D96 ; Lo # [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA +0D9A..0DB1 ; Lo # [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA +0DB3..0DBB ; Lo # [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA +0DBD ; Lo # SINHALA LETTER DANTAJA LAYANNA +0DC0..0DC6 ; Lo # [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA +0E01..0E30 ; Lo # [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A +0E32..0E33 ; Lo # [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM +0E40..0E45 ; Lo # [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO +0E81..0E82 ; Lo # [2] LAO LETTER KO..LAO LETTER KHO SUNG +0E84 ; Lo # LAO LETTER KHO TAM +0E87..0E88 ; Lo # [2] LAO LETTER NGO..LAO LETTER CO +0E8A ; Lo # LAO LETTER SO TAM +0E8D ; Lo # LAO LETTER NYO +0E94..0E97 ; Lo # [4] LAO LETTER DO..LAO LETTER THO TAM +0E99..0E9F ; Lo # [7] LAO LETTER NO..LAO LETTER FO SUNG +0EA1..0EA3 ; Lo # [3] LAO LETTER MO..LAO LETTER LO LING +0EA5 ; Lo # LAO LETTER LO LOOT +0EA7 ; Lo # LAO LETTER WO +0EAA..0EAB ; Lo # [2] LAO LETTER SO SUNG..LAO LETTER HO SUNG +0EAD..0EB0 ; Lo # [4] LAO LETTER O..LAO VOWEL SIGN A +0EB2..0EB3 ; Lo # [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM +0EBD ; Lo # LAO SEMIVOWEL SIGN NYO +0EC0..0EC4 ; Lo # [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI +0EDC..0EDF ; Lo # [4] LAO HO NO..LAO LETTER KHMU NYO +0F00 ; Lo # TIBETAN SYLLABLE OM +0F40..0F47 ; Lo # [8] TIBETAN LETTER KA..TIBETAN LETTER JA +0F49..0F6C ; Lo # [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA +0F88..0F8C ; Lo # [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN +1000..102A ; Lo # [43] MYANMAR LETTER KA..MYANMAR LETTER AU +103F ; Lo # MYANMAR LETTER GREAT SA +1050..1055 ; Lo # [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL +105A..105D ; Lo # [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE +1061 ; Lo # MYANMAR LETTER SGAW KAREN SHA +1065..1066 ; Lo # [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA +106E..1070 ; Lo # [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA +1075..1081 ; Lo # [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA +108E ; Lo # MYANMAR LETTER RUMAI PALAUNG FA +10D0..10FA ; Lo # [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN +10FD..1248 ; Lo # [332] GEORGIAN LETTER AEN..ETHIOPIC SYLLABLE QWA +124A..124D ; Lo # [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE +1250..1256 ; Lo # [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO +1258 ; Lo # ETHIOPIC SYLLABLE QHWA +125A..125D ; Lo # [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE +1260..1288 ; Lo # [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA +128A..128D ; Lo # [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE +1290..12B0 ; Lo # [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA +12B2..12B5 ; Lo # [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE +12B8..12BE ; Lo # [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO +12C0 ; Lo # ETHIOPIC SYLLABLE KXWA +12C2..12C5 ; Lo # [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE +12C8..12D6 ; Lo # [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O +12D8..1310 ; Lo # [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA +1312..1315 ; Lo # [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE +1318..135A ; Lo # [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA +1380..138F ; Lo # [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE +1401..166C ; Lo # [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA +166F..167F ; Lo # [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W +1681..169A ; Lo # [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH +16A0..16EA ; Lo # [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X +16F1..16F8 ; Lo # [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC +1700..170C ; Lo # [13] TAGALOG LETTER A..TAGALOG LETTER YA +170E..1711 ; Lo # [4] TAGALOG LETTER LA..TAGALOG LETTER HA +1720..1731 ; Lo # [18] HANUNOO LETTER A..HANUNOO LETTER HA +1740..1751 ; Lo # [18] BUHID LETTER A..BUHID LETTER HA +1760..176C ; Lo # [13] TAGBANWA LETTER A..TAGBANWA LETTER YA +176E..1770 ; Lo # [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA +1780..17B3 ; Lo # [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU +17DC ; Lo # KHMER SIGN AVAKRAHASANYA +1820..1842 ; Lo # [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI +1844..1877 ; Lo # [52] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER MANCHU ZHA +1880..1884 ; Lo # [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA +1887..18A8 ; Lo # [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA +18AA ; Lo # MONGOLIAN LETTER MANCHU ALI GALI LHA +18B0..18F5 ; Lo # [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S +1900..191E ; Lo # [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA +1950..196D ; Lo # [30] TAI LE LETTER KA..TAI LE LETTER AI +1970..1974 ; Lo # [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6 +1980..19AB ; Lo # [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA +19B0..19C9 ; Lo # [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2 +1A00..1A16 ; Lo # [23] BUGINESE LETTER KA..BUGINESE LETTER HA +1A20..1A54 ; Lo # [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA +1B05..1B33 ; Lo # [47] BALINESE LETTER AKARA..BALINESE LETTER HA +1B45..1B4B ; Lo # [7] BALINESE LETTER KAF SASAK..BALINESE LETTER ASYURA SASAK +1B83..1BA0 ; Lo # [30] SUNDANESE LETTER A..SUNDANESE LETTER HA +1BAE..1BAF ; Lo # [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA +1BBA..1BE5 ; Lo # [44] SUNDANESE AVAGRAHA..BATAK LETTER U +1C00..1C23 ; Lo # [36] LEPCHA LETTER KA..LEPCHA LETTER A +1C4D..1C4F ; Lo # [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA +1C5A..1C77 ; Lo # [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH +1CE9..1CEC ; Lo # [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL +1CEE..1CF1 ; Lo # [4] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ANUSVARA UBHAYATO MUKHA +1CF5..1CF6 ; Lo # [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA +2135..2138 ; Lo # [4] ALEF SYMBOL..DALET SYMBOL +2D30..2D67 ; Lo # [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO +2D80..2D96 ; Lo # [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE +2DA0..2DA6 ; Lo # [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO +2DA8..2DAE ; Lo # [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO +2DB0..2DB6 ; Lo # [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO +2DB8..2DBE ; Lo # [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO +2DC0..2DC6 ; Lo # [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO +2DC8..2DCE ; Lo # [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO +2DD0..2DD6 ; Lo # [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO +2DD8..2DDE ; Lo # [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO +3006 ; Lo # IDEOGRAPHIC CLOSING MARK +303C ; Lo # MASU MARK +3041..3096 ; Lo # [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE +309F ; Lo # HIRAGANA DIGRAPH YORI +30A1..30FA ; Lo # [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO +30FF ; Lo # KATAKANA DIGRAPH KOTO +3105..312D ; Lo # [41] BOPOMOFO LETTER B..BOPOMOFO LETTER IH +3131..318E ; Lo # [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE +31A0..31BA ; Lo # [27] BOPOMOFO LETTER BU..BOPOMOFO LETTER ZY +31F0..31FF ; Lo # [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO +3400..4DB5 ; Lo # [6582] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DB5 +4E00..9FD5 ; Lo # [20950] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FD5 +A000..A014 ; Lo # [21] YI SYLLABLE IT..YI SYLLABLE E +A016..A48C ; Lo # [1143] YI SYLLABLE BIT..YI SYLLABLE YYR +A4D0..A4F7 ; Lo # [40] LISU LETTER BA..LISU LETTER OE +A500..A60B ; Lo # [268] VAI SYLLABLE EE..VAI SYLLABLE NG +A610..A61F ; Lo # [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG +A62A..A62B ; Lo # [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO +A66E ; Lo # CYRILLIC LETTER MULTIOCULAR O +A6A0..A6E5 ; Lo # [70] BAMUM LETTER A..BAMUM LETTER KI +A78F ; Lo # LATIN LETTER SINOLOGICAL DOT +A7F7 ; Lo # LATIN EPIGRAPHIC LETTER SIDEWAYS I +A7FB..A801 ; Lo # [7] LATIN EPIGRAPHIC LETTER REVERSED F..SYLOTI NAGRI LETTER I +A803..A805 ; Lo # [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O +A807..A80A ; Lo # [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO +A80C..A822 ; Lo # [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO +A840..A873 ; Lo # [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU +A882..A8B3 ; Lo # [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA +A8F2..A8F7 ; Lo # [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA +A8FB ; Lo # DEVANAGARI HEADSTROKE +A8FD ; Lo # DEVANAGARI JAIN OM +A90A..A925 ; Lo # [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO +A930..A946 ; Lo # [23] REJANG LETTER KA..REJANG LETTER A +A960..A97C ; Lo # [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH +A984..A9B2 ; Lo # [47] JAVANESE LETTER A..JAVANESE LETTER HA +A9E0..A9E4 ; Lo # [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA +A9E7..A9EF ; Lo # [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA +A9FA..A9FE ; Lo # [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA +AA00..AA28 ; Lo # [41] CHAM LETTER A..CHAM LETTER HA +AA40..AA42 ; Lo # [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG +AA44..AA4B ; Lo # [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS +AA60..AA6F ; Lo # [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA +AA71..AA76 ; Lo # [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM +AA7A ; Lo # MYANMAR LETTER AITON RA +AA7E..AAAF ; Lo # [50] MYANMAR LETTER SHWE PALAUNG CHA..TAI VIET LETTER HIGH O +AAB1 ; Lo # TAI VIET VOWEL AA +AAB5..AAB6 ; Lo # [2] TAI VIET VOWEL E..TAI VIET VOWEL O +AAB9..AABD ; Lo # [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN +AAC0 ; Lo # TAI VIET TONE MAI NUENG +AAC2 ; Lo # TAI VIET TONE MAI SONG +AADB..AADC ; Lo # [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG +AAE0..AAEA ; Lo # [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA +AAF2 ; Lo # MEETEI MAYEK ANJI +AB01..AB06 ; Lo # [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO +AB09..AB0E ; Lo # [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO +AB11..AB16 ; Lo # [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO +AB20..AB26 ; Lo # [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO +AB28..AB2E ; Lo # [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO +ABC0..ABE2 ; Lo # [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM +AC00..D7A3 ; Lo # [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH +D7B0..D7C6 ; Lo # [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E +D7CB..D7FB ; Lo # [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH +F900..FA6D ; Lo # [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D +FA70..FAD9 ; Lo # [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +FB1D ; Lo # HEBREW LETTER YOD WITH HIRIQ +FB1F..FB28 ; Lo # [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV +FB2A..FB36 ; Lo # [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH +FB38..FB3C ; Lo # [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH +FB3E ; Lo # HEBREW LETTER MEM WITH DAGESH +FB40..FB41 ; Lo # [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH +FB43..FB44 ; Lo # [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH +FB46..FBB1 ; Lo # [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM +FBD3..FD3D ; Lo # [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +FD50..FD8F ; Lo # [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM +FD92..FDC7 ; Lo # [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FDF0..FDFB ; Lo # [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU +FE70..FE74 ; Lo # [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM +FE76..FEFC ; Lo # [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM +FF66..FF6F ; Lo # [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU +FF71..FF9D ; Lo # [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N +FFA0..FFBE ; Lo # [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH +FFC2..FFC7 ; Lo # [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E +FFCA..FFCF ; Lo # [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE +FFD2..FFD7 ; Lo # [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU +FFDA..FFDC ; Lo # [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I +10000..1000B ; Lo # [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE +1000D..10026 ; Lo # [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO +10028..1003A ; Lo # [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO +1003C..1003D ; Lo # [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE +1003F..1004D ; Lo # [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO +10050..1005D ; Lo # [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089 +10080..100FA ; Lo # [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305 +10280..1029C ; Lo # [29] LYCIAN LETTER A..LYCIAN LETTER X +102A0..102D0 ; Lo # [49] CARIAN LETTER A..CARIAN LETTER UUU3 +10300..1031F ; Lo # [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS +10330..10340 ; Lo # [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA +10342..10349 ; Lo # [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL +10350..10375 ; Lo # [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA +10380..1039D ; Lo # [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU +103A0..103C3 ; Lo # [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA +103C8..103CF ; Lo # [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH +10450..1049D ; Lo # [78] SHAVIAN LETTER PEEP..OSMANYA LETTER OO +10500..10527 ; Lo # [40] ELBASAN LETTER A..ELBASAN LETTER KHE +10530..10563 ; Lo # [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW +10600..10736 ; Lo # [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 +10740..10755 ; Lo # [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE +10760..10767 ; Lo # [8] LINEAR A SIGN A800..LINEAR A SIGN A807 +10800..10805 ; Lo # [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA +10808 ; Lo # CYPRIOT SYLLABLE JO +1080A..10835 ; Lo # [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO +10837..10838 ; Lo # [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE +1083C ; Lo # CYPRIOT SYLLABLE ZA +1083F..10855 ; Lo # [23] CYPRIOT SYLLABLE ZO..IMPERIAL ARAMAIC LETTER TAW +10860..10876 ; Lo # [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW +10880..1089E ; Lo # [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW +108E0..108F2 ; Lo # [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH +108F4..108F5 ; Lo # [2] HATRAN LETTER SHIN..HATRAN LETTER TAW +10900..10915 ; Lo # [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU +10920..10939 ; Lo # [26] LYDIAN LETTER A..LYDIAN LETTER C +10980..109B7 ; Lo # [56] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC CURSIVE LETTER DA +109BE..109BF ; Lo # [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN +10A00 ; Lo # KHAROSHTHI LETTER A +10A10..10A13 ; Lo # [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA +10A15..10A17 ; Lo # [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA +10A19..10A33 ; Lo # [27] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER TTTHA +10A60..10A7C ; Lo # [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH +10A80..10A9C ; Lo # [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH +10AC0..10AC7 ; Lo # [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW +10AC9..10AE4 ; Lo # [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW +10B00..10B35 ; Lo # [54] AVESTAN LETTER A..AVESTAN LETTER HE +10B40..10B55 ; Lo # [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW +10B60..10B72 ; Lo # [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW +10B80..10B91 ; Lo # [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW +10C00..10C48 ; Lo # [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH +11003..11037 ; Lo # [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA +11083..110AF ; Lo # [45] KAITHI LETTER A..KAITHI LETTER HA +110D0..110E8 ; Lo # [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE +11103..11126 ; Lo # [36] CHAKMA LETTER AA..CHAKMA LETTER HAA +11150..11172 ; Lo # [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA +11176 ; Lo # MAHAJANI LIGATURE SHRI +11183..111B2 ; Lo # [48] SHARADA LETTER A..SHARADA LETTER HA +111C1..111C4 ; Lo # [4] SHARADA SIGN AVAGRAHA..SHARADA OM +111DA ; Lo # SHARADA EKAM +111DC ; Lo # SHARADA HEADSTROKE +11200..11211 ; Lo # [18] KHOJKI LETTER A..KHOJKI LETTER JJA +11213..1122B ; Lo # [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA +11280..11286 ; Lo # [7] MULTANI LETTER A..MULTANI LETTER GA +11288 ; Lo # MULTANI LETTER GHA +1128A..1128D ; Lo # [4] MULTANI LETTER CA..MULTANI LETTER JJA +1128F..1129D ; Lo # [15] MULTANI LETTER NYA..MULTANI LETTER BA +1129F..112A8 ; Lo # [10] MULTANI LETTER BHA..MULTANI LETTER RHA +112B0..112DE ; Lo # [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA +11305..1130C ; Lo # [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L +1130F..11310 ; Lo # [2] GRANTHA LETTER EE..GRANTHA LETTER AI +11313..11328 ; Lo # [22] GRANTHA LETTER OO..GRANTHA LETTER NA +1132A..11330 ; Lo # [7] GRANTHA LETTER PA..GRANTHA LETTER RA +11332..11333 ; Lo # [2] GRANTHA LETTER LA..GRANTHA LETTER LLA +11335..11339 ; Lo # [5] GRANTHA LETTER VA..GRANTHA LETTER HA +1133D ; Lo # GRANTHA SIGN AVAGRAHA +11350 ; Lo # GRANTHA OM +1135D..11361 ; Lo # [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL +11400..11434 ; Lo # [53] NEWA LETTER A..NEWA LETTER HA +11447..1144A ; Lo # [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI +11480..114AF ; Lo # [48] TIRHUTA ANJI..TIRHUTA LETTER HA +114C4..114C5 ; Lo # [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG +114C7 ; Lo # TIRHUTA OM +11580..115AE ; Lo # [47] SIDDHAM LETTER A..SIDDHAM LETTER HA +115D8..115DB ; Lo # [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U +11600..1162F ; Lo # [48] MODI LETTER A..MODI LETTER LLA +11644 ; Lo # MODI SIGN HUVA +11680..116AA ; Lo # [43] TAKRI LETTER A..TAKRI LETTER RRA +11700..11719 ; Lo # [26] AHOM LETTER KA..AHOM LETTER JHA +118FF ; Lo # WARANG CITI OM +11AC0..11AF8 ; Lo # [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL +11C00..11C08 ; Lo # [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L +11C0A..11C2E ; Lo # [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA +11C40 ; Lo # BHAIKSUKI SIGN AVAGRAHA +11C72..11C8F ; Lo # [30] MARCHEN LETTER KA..MARCHEN LETTER A +12000..12399 ; Lo # [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U +12480..12543 ; Lo # [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU +13000..1342E ; Lo # [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032 +14400..14646 ; Lo # [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16800..16A38 ; Lo # [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ +16A40..16A5E ; Lo # [31] MRO LETTER TA..MRO LETTER TEK +16AD0..16AED ; Lo # [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I +16B00..16B2F ; Lo # [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU +16B63..16B77 ; Lo # [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS +16B7D..16B8F ; Lo # [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16F00..16F44 ; Lo # [69] MIAO LETTER PA..MIAO LETTER HHA +16F50 ; Lo # MIAO LETTER NASALIZATION +17000..187EC ; Lo # [6125] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187EC +18800..18AF2 ; Lo # [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755 +1B000..1B001 ; Lo # [2] KATAKANA LETTER ARCHAIC E..HIRAGANA LETTER ARCHAIC YE +1BC00..1BC6A ; Lo # [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M +1BC70..1BC7C ; Lo # [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK +1BC80..1BC88 ; Lo # [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL +1BC90..1BC99 ; Lo # [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW +1E800..1E8C4 ; Lo # [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON +1EE00..1EE03 ; Lo # [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL +1EE05..1EE1F ; Lo # [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF +1EE21..1EE22 ; Lo # [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM +1EE24 ; Lo # ARABIC MATHEMATICAL INITIAL HEH +1EE27 ; Lo # ARABIC MATHEMATICAL INITIAL HAH +1EE29..1EE32 ; Lo # [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF +1EE34..1EE37 ; Lo # [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH +1EE39 ; Lo # ARABIC MATHEMATICAL INITIAL DAD +1EE3B ; Lo # ARABIC MATHEMATICAL INITIAL GHAIN +1EE42 ; Lo # ARABIC MATHEMATICAL TAILED JEEM +1EE47 ; Lo # ARABIC MATHEMATICAL TAILED HAH +1EE49 ; Lo # ARABIC MATHEMATICAL TAILED YEH +1EE4B ; Lo # ARABIC MATHEMATICAL TAILED LAM +1EE4D..1EE4F ; Lo # [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN +1EE51..1EE52 ; Lo # [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF +1EE54 ; Lo # ARABIC MATHEMATICAL TAILED SHEEN +1EE57 ; Lo # ARABIC MATHEMATICAL TAILED KHAH +1EE59 ; Lo # ARABIC MATHEMATICAL TAILED DAD +1EE5B ; Lo # ARABIC MATHEMATICAL TAILED GHAIN +1EE5D ; Lo # ARABIC MATHEMATICAL TAILED DOTLESS NOON +1EE5F ; Lo # ARABIC MATHEMATICAL TAILED DOTLESS QAF +1EE61..1EE62 ; Lo # [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM +1EE64 ; Lo # ARABIC MATHEMATICAL STRETCHED HEH +1EE67..1EE6A ; Lo # [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF +1EE6C..1EE72 ; Lo # [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF +1EE74..1EE77 ; Lo # [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH +1EE79..1EE7C ; Lo # [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH +1EE7E ; Lo # ARABIC MATHEMATICAL STRETCHED DOTLESS FEH +1EE80..1EE89 ; Lo # [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH +1EE8B..1EE9B ; Lo # [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN +1EEA1..1EEA3 ; Lo # [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL +1EEA5..1EEA9 ; Lo # [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH +1EEAB..1EEBB ; Lo # [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN +20000..2A6D6 ; Lo # [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6 +2A700..2B734 ; Lo # [4149] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734 +2B740..2B81D ; Lo # [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D +2B820..2CEA1 ; Lo # [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1 +2F800..2FA1D ; Lo # [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 112721 + +# ================================================ + +# General_Category=Nonspacing_Mark + +0300..036F ; Mn # [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X +0483..0487 ; Mn # [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE +0591..05BD ; Mn # [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG +05BF ; Mn # HEBREW POINT RAFE +05C1..05C2 ; Mn # [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT +05C4..05C5 ; Mn # [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT +05C7 ; Mn # HEBREW POINT QAMATS QATAN +0610..061A ; Mn # [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA +064B..065F ; Mn # [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW +0670 ; Mn # ARABIC LETTER SUPERSCRIPT ALEF +06D6..06DC ; Mn # [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN +06DF..06E4 ; Mn # [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA +06E7..06E8 ; Mn # [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +06EA..06ED ; Mn # [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM +0711 ; Mn # SYRIAC LETTER SUPERSCRIPT ALAPH +0730..074A ; Mn # [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH +07A6..07B0 ; Mn # [11] THAANA ABAFILI..THAANA SUKUN +07EB..07F3 ; Mn # [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE +0816..0819 ; Mn # [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH +081B..0823 ; Mn # [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A +0825..0827 ; Mn # [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U +0829..082D ; Mn # [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA +0859..085B ; Mn # [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK +08D4..08E1 ; Mn # [14] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH SIGN SAFHA +08E3..0902 ; Mn # [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA +093A ; Mn # DEVANAGARI VOWEL SIGN OE +093C ; Mn # DEVANAGARI SIGN NUKTA +0941..0948 ; Mn # [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +094D ; Mn # DEVANAGARI SIGN VIRAMA +0951..0957 ; Mn # [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE +0962..0963 ; Mn # [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0981 ; Mn # BENGALI SIGN CANDRABINDU +09BC ; Mn # BENGALI SIGN NUKTA +09C1..09C4 ; Mn # [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09CD ; Mn # BENGALI SIGN VIRAMA +09E2..09E3 ; Mn # [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL +0A01..0A02 ; Mn # [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI +0A3C ; Mn # GURMUKHI SIGN NUKTA +0A41..0A42 ; Mn # [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; Mn # [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4D ; Mn # [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA +0A51 ; Mn # GURMUKHI SIGN UDAAT +0A70..0A71 ; Mn # [2] GURMUKHI TIPPI..GURMUKHI ADDAK +0A75 ; Mn # GURMUKHI SIGN YAKASH +0A81..0A82 ; Mn # [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA +0ABC ; Mn # GUJARATI SIGN NUKTA +0AC1..0AC5 ; Mn # [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC8 ; Mn # [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI +0ACD ; Mn # GUJARATI SIGN VIRAMA +0AE2..0AE3 ; Mn # [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL +0B01 ; Mn # ORIYA SIGN CANDRABINDU +0B3C ; Mn # ORIYA SIGN NUKTA +0B3F ; Mn # ORIYA VOWEL SIGN I +0B41..0B44 ; Mn # [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR +0B4D ; Mn # ORIYA SIGN VIRAMA +0B56 ; Mn # ORIYA AI LENGTH MARK +0B62..0B63 ; Mn # [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL +0B82 ; Mn # TAMIL SIGN ANUSVARA +0BC0 ; Mn # TAMIL VOWEL SIGN II +0BCD ; Mn # TAMIL SIGN VIRAMA +0C00 ; Mn # TELUGU SIGN COMBINING CANDRABINDU ABOVE +0C3E..0C40 ; Mn # [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II +0C46..0C48 ; Mn # [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4D ; Mn # [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA +0C55..0C56 ; Mn # [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C62..0C63 ; Mn # [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL +0C81 ; Mn # KANNADA SIGN CANDRABINDU +0CBC ; Mn # KANNADA SIGN NUKTA +0CBF ; Mn # KANNADA VOWEL SIGN I +0CC6 ; Mn # KANNADA VOWEL SIGN E +0CCC..0CCD ; Mn # [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA +0CE2..0CE3 ; Mn # [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL +0D01 ; Mn # MALAYALAM SIGN CANDRABINDU +0D41..0D44 ; Mn # [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR +0D4D ; Mn # MALAYALAM SIGN VIRAMA +0D62..0D63 ; Mn # [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL +0DCA ; Mn # SINHALA SIGN AL-LAKUNA +0DD2..0DD4 ; Mn # [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; Mn # SINHALA VOWEL SIGN DIGA PAA-PILLA +0E31 ; Mn # THAI CHARACTER MAI HAN-AKAT +0E34..0E3A ; Mn # [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E47..0E4E ; Mn # [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN +0EB1 ; Mn # LAO VOWEL SIGN MAI KAN +0EB4..0EB9 ; Mn # [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU +0EBB..0EBC ; Mn # [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO +0EC8..0ECD ; Mn # [6] LAO TONE MAI EK..LAO NIGGAHITA +0F18..0F19 ; Mn # [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS +0F35 ; Mn # TIBETAN MARK NGAS BZUNG NYI ZLA +0F37 ; Mn # TIBETAN MARK NGAS BZUNG SGOR RTAGS +0F39 ; Mn # TIBETAN MARK TSA -PHRU +0F71..0F7E ; Mn # [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO +0F80..0F84 ; Mn # [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA +0F86..0F87 ; Mn # [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS +0F8D..0F97 ; Mn # [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA +0F99..0FBC ; Mn # [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA +0FC6 ; Mn # TIBETAN SYMBOL PADMA GDAN +102D..1030 ; Mn # [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU +1032..1037 ; Mn # [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW +1039..103A ; Mn # [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT +103D..103E ; Mn # [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA +1058..1059 ; Mn # [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL +105E..1060 ; Mn # [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA +1071..1074 ; Mn # [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE +1082 ; Mn # MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1085..1086 ; Mn # [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y +108D ; Mn # MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE +109D ; Mn # MYANMAR VOWEL SIGN AITON AI +135D..135F ; Mn # [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK +1712..1714 ; Mn # [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1732..1734 ; Mn # [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD +1752..1753 ; Mn # [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U +1772..1773 ; Mn # [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U +17B4..17B5 ; Mn # [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA +17B7..17BD ; Mn # [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA +17C6 ; Mn # KHMER SIGN NIKAHIT +17C9..17D3 ; Mn # [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT +17DD ; Mn # KHMER SIGN ATTHACAN +180B..180D ; Mn # [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +1885..1886 ; Mn # [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA +18A9 ; Mn # MONGOLIAN LETTER ALI GALI DAGALGA +1920..1922 ; Mn # [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U +1927..1928 ; Mn # [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O +1932 ; Mn # LIMBU SMALL LETTER ANUSVARA +1939..193B ; Mn # [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I +1A17..1A18 ; Mn # [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U +1A1B ; Mn # BUGINESE VOWEL SIGN AE +1A56 ; Mn # TAI THAM CONSONANT SIGN MEDIAL LA +1A58..1A5E ; Mn # [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA +1A60 ; Mn # TAI THAM SIGN SAKOT +1A62 ; Mn # TAI THAM VOWEL SIGN MAI SAT +1A65..1A6C ; Mn # [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW +1A73..1A7C ; Mn # [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN +1A7F ; Mn # TAI THAM COMBINING CRYPTOGRAMMIC DOT +1AB0..1ABD ; Mn # [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW +1B00..1B03 ; Mn # [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG +1B34 ; Mn # BALINESE SIGN REREKAN +1B36..1B3A ; Mn # [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3C ; Mn # BALINESE VOWEL SIGN LA LENGA +1B42 ; Mn # BALINESE VOWEL SIGN PEPET +1B6B..1B73 ; Mn # [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG +1B80..1B81 ; Mn # [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR +1BA2..1BA5 ; Mn # [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU +1BA8..1BA9 ; Mn # [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAB..1BAD ; Mn # [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA +1BE6 ; Mn # BATAK SIGN TOMPI +1BE8..1BE9 ; Mn # [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE +1BED ; Mn # BATAK VOWEL SIGN KARO O +1BEF..1BF1 ; Mn # [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1C2C..1C33 ; Mn # [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T +1C36..1C37 ; Mn # [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA +1CD0..1CD2 ; Mn # [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA +1CD4..1CE0 ; Mn # [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA +1CE2..1CE8 ; Mn # [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL +1CED ; Mn # VEDIC SIGN TIRYAK +1CF4 ; Mn # VEDIC TONE CANDRA ABOVE +1CF8..1CF9 ; Mn # [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE +1DC0..1DF5 ; Mn # [54] COMBINING DOTTED GRAVE ACCENT..COMBINING UP TACK ABOVE +1DFB..1DFF ; Mn # [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +20D0..20DC ; Mn # [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20E1 ; Mn # COMBINING LEFT RIGHT ARROW ABOVE +20E5..20F0 ; Mn # [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE +2CEF..2CF1 ; Mn # [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS +2D7F ; Mn # TIFINAGH CONSONANT JOINER +2DE0..2DFF ; Mn # [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS +302A..302D ; Mn # [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK +3099..309A ; Mn # [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +A66F ; Mn # COMBINING CYRILLIC VZMET +A674..A67D ; Mn # [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK +A69E..A69F ; Mn # [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E +A6F0..A6F1 ; Mn # [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS +A802 ; Mn # SYLOTI NAGRI SIGN DVISVARA +A806 ; Mn # SYLOTI NAGRI SIGN HASANTA +A80B ; Mn # SYLOTI NAGRI SIGN ANUSVARA +A825..A826 ; Mn # [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E +A8C4..A8C5 ; Mn # [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU +A8E0..A8F1 ; Mn # [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA +A926..A92D ; Mn # [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU +A947..A951 ; Mn # [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A980..A982 ; Mn # [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR +A9B3 ; Mn # JAVANESE SIGN CECAK TELU +A9B6..A9B9 ; Mn # [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT +A9BC ; Mn # JAVANESE VOWEL SIGN PEPET +A9E5 ; Mn # MYANMAR SIGN SHAN SAW +AA29..AA2E ; Mn # [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE +AA31..AA32 ; Mn # [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE +AA35..AA36 ; Mn # [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA +AA43 ; Mn # CHAM CONSONANT SIGN FINAL NG +AA4C ; Mn # CHAM CONSONANT SIGN FINAL M +AA7C ; Mn # MYANMAR SIGN TAI LAING TONE-2 +AAB0 ; Mn # TAI VIET MAI KANG +AAB2..AAB4 ; Mn # [3] TAI VIET VOWEL I..TAI VIET VOWEL U +AAB7..AAB8 ; Mn # [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA +AABE..AABF ; Mn # [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK +AAC1 ; Mn # TAI VIET TONE MAI THO +AAEC..AAED ; Mn # [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI +AAF6 ; Mn # MEETEI MAYEK VIRAMA +ABE5 ; Mn # MEETEI MAYEK VOWEL SIGN ANAP +ABE8 ; Mn # MEETEI MAYEK VOWEL SIGN UNAP +ABED ; Mn # MEETEI MAYEK APUN IYEK +FB1E ; Mn # HEBREW POINT JUDEO-SPANISH VARIKA +FE00..FE0F ; Mn # [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 +FE20..FE2F ; Mn # [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF +101FD ; Mn # PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE +102E0 ; Mn # COPTIC EPACT THOUSANDS MARK +10376..1037A ; Mn # [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII +10A01..10A03 ; Mn # [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R +10A05..10A06 ; Mn # [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O +10A0C..10A0F ; Mn # [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA +10A38..10A3A ; Mn # [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW +10A3F ; Mn # KHAROSHTHI VIRAMA +10AE5..10AE6 ; Mn # [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW +11001 ; Mn # BRAHMI SIGN ANUSVARA +11038..11046 ; Mn # [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA +1107F..11081 ; Mn # [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA +110B3..110B6 ; Mn # [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI +110B9..110BA ; Mn # [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +11100..11102 ; Mn # [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA +11127..1112B ; Mn # [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU +1112D..11134 ; Mn # [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA +11173 ; Mn # MAHAJANI SIGN NUKTA +11180..11181 ; Mn # [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA +111B6..111BE ; Mn # [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O +111CA..111CC ; Mn # [3] SHARADA SIGN NUKTA..SHARADA EXTRA SHORT VOWEL MARK +1122F..11231 ; Mn # [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI +11234 ; Mn # KHOJKI SIGN ANUSVARA +11236..11237 ; Mn # [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA +1123E ; Mn # KHOJKI SIGN SUKUN +112DF ; Mn # KHUDAWADI SIGN ANUSVARA +112E3..112EA ; Mn # [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA +11300..11301 ; Mn # [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU +1133C ; Mn # GRANTHA SIGN NUKTA +11340 ; Mn # GRANTHA VOWEL SIGN II +11366..1136C ; Mn # [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX +11370..11374 ; Mn # [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +11438..1143F ; Mn # [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI +11442..11444 ; Mn # [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA +11446 ; Mn # NEWA SIGN NUKTA +114B3..114B8 ; Mn # [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL +114BA ; Mn # TIRHUTA VOWEL SIGN SHORT E +114BF..114C0 ; Mn # [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA +114C2..114C3 ; Mn # [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA +115B2..115B5 ; Mn # [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR +115BC..115BD ; Mn # [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA +115BF..115C0 ; Mn # [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA +115DC..115DD ; Mn # [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU +11633..1163A ; Mn # [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI +1163D ; Mn # MODI SIGN ANUSVARA +1163F..11640 ; Mn # [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA +116AB ; Mn # TAKRI SIGN ANUSVARA +116AD ; Mn # TAKRI VOWEL SIGN AA +116B0..116B5 ; Mn # [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU +116B7 ; Mn # TAKRI SIGN NUKTA +1171D..1171F ; Mn # [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +11722..11725 ; Mn # [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU +11727..1172B ; Mn # [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER +11C30..11C36 ; Mn # [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L +11C38..11C3D ; Mn # [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA +11C3F ; Mn # BHAIKSUKI SIGN VIRAMA +11C92..11CA7 ; Mn # [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA +11CAA..11CB0 ; Mn # [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA +11CB2..11CB3 ; Mn # [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E +11CB5..11CB6 ; Mn # [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU +16AF0..16AF4 ; Mn # [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE +16B30..16B36 ; Mn # [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM +16F8F..16F92 ; Mn # [4] MIAO TONE RIGHT..MIAO TONE BELOW +1BC9D..1BC9E ; Mn # [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1D167..1D169 ; Mn # [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 +1D17B..1D182 ; Mn # [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE +1D185..1D18B ; Mn # [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE +1D1AA..1D1AD ; Mn # [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO +1D242..1D244 ; Mn # [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME +1DA00..1DA36 ; Mn # [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN +1DA3B..1DA6C ; Mn # [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT +1DA75 ; Mn # SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS +1DA84 ; Mn # SIGNWRITING LOCATION HEAD NECK +1DA9B..1DA9F ; Mn # [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 +1DAA1..1DAAF ; Mn # [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 +1E000..1E006 ; Mn # [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE +1E008..1E018 ; Mn # [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU +1E01B..1E021 ; Mn # [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI +1E023..1E024 ; Mn # [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS +1E026..1E02A ; Mn # [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA +1E8D0..1E8D6 ; Mn # [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS +1E944..1E94A ; Mn # [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA +E0100..E01EF ; Mn # [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 + +# Total code points: 1690 + +# ================================================ + +# General_Category=Enclosing_Mark + +0488..0489 ; Me # [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN +1ABE ; Me # COMBINING PARENTHESES OVERLAY +20DD..20E0 ; Me # [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH +20E2..20E4 ; Me # [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE +A670..A672 ; Me # [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN + +# Total code points: 13 + +# ================================================ + +# General_Category=Spacing_Mark + +0903 ; Mc # DEVANAGARI SIGN VISARGA +093B ; Mc # DEVANAGARI VOWEL SIGN OOE +093E..0940 ; Mc # [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II +0949..094C ; Mc # [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU +094E..094F ; Mc # [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW +0982..0983 ; Mc # [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA +09BE..09C0 ; Mc # [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II +09C7..09C8 ; Mc # [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI +09CB..09CC ; Mc # [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU +09D7 ; Mc # BENGALI AU LENGTH MARK +0A03 ; Mc # GURMUKHI SIGN VISARGA +0A3E..0A40 ; Mc # [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II +0A83 ; Mc # GUJARATI SIGN VISARGA +0ABE..0AC0 ; Mc # [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II +0AC9 ; Mc # GUJARATI VOWEL SIGN CANDRA O +0ACB..0ACC ; Mc # [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU +0B02..0B03 ; Mc # [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA +0B3E ; Mc # ORIYA VOWEL SIGN AA +0B40 ; Mc # ORIYA VOWEL SIGN II +0B47..0B48 ; Mc # [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI +0B4B..0B4C ; Mc # [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU +0B57 ; Mc # ORIYA AU LENGTH MARK +0BBE..0BBF ; Mc # [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I +0BC1..0BC2 ; Mc # [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU +0BC6..0BC8 ; Mc # [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI +0BCA..0BCC ; Mc # [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU +0BD7 ; Mc # TAMIL AU LENGTH MARK +0C01..0C03 ; Mc # [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA +0C41..0C44 ; Mc # [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR +0C82..0C83 ; Mc # [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA +0CBE ; Mc # KANNADA VOWEL SIGN AA +0CC0..0CC4 ; Mc # [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR +0CC7..0CC8 ; Mc # [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Mc # [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO +0CD5..0CD6 ; Mc # [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0D02..0D03 ; Mc # [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA +0D3E..0D40 ; Mc # [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II +0D46..0D48 ; Mc # [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI +0D4A..0D4C ; Mc # [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU +0D57 ; Mc # MALAYALAM AU LENGTH MARK +0D82..0D83 ; Mc # [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA +0DCF..0DD1 ; Mc # [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA +0DD8..0DDF ; Mc # [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA +0DF2..0DF3 ; Mc # [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA +0F3E..0F3F ; Mc # [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES +0F7F ; Mc # TIBETAN SIGN RNAM BCAD +102B..102C ; Mc # [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA +1031 ; Mc # MYANMAR VOWEL SIGN E +1038 ; Mc # MYANMAR SIGN VISARGA +103B..103C ; Mc # [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA +1056..1057 ; Mc # [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR +1062..1064 ; Mc # [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO +1067..106D ; Mc # [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 +1083..1084 ; Mc # [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E +1087..108C ; Mc # [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 +108F ; Mc # MYANMAR SIGN RUMAI PALAUNG TONE-5 +109A..109C ; Mc # [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A +17B6 ; Mc # KHMER VOWEL SIGN AA +17BE..17C5 ; Mc # [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU +17C7..17C8 ; Mc # [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU +1923..1926 ; Mc # [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU +1929..192B ; Mc # [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA +1930..1931 ; Mc # [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA +1933..1938 ; Mc # [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA +1A19..1A1A ; Mc # [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O +1A55 ; Mc # TAI THAM CONSONANT SIGN MEDIAL RA +1A57 ; Mc # TAI THAM CONSONANT SIGN LA TANG LAI +1A61 ; Mc # TAI THAM VOWEL SIGN A +1A63..1A64 ; Mc # [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA +1A6D..1A72 ; Mc # [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI +1B04 ; Mc # BALINESE SIGN BISAH +1B35 ; Mc # BALINESE VOWEL SIGN TEDUNG +1B3B ; Mc # BALINESE VOWEL SIGN RA REPA TEDUNG +1B3D..1B41 ; Mc # [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG +1B43..1B44 ; Mc # [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG +1B82 ; Mc # SUNDANESE SIGN PANGWISAD +1BA1 ; Mc # SUNDANESE CONSONANT SIGN PAMINGKAL +1BA6..1BA7 ; Mc # [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG +1BAA ; Mc # SUNDANESE SIGN PAMAAEH +1BE7 ; Mc # BATAK VOWEL SIGN E +1BEA..1BEC ; Mc # [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O +1BEE ; Mc # BATAK VOWEL SIGN U +1BF2..1BF3 ; Mc # [2] BATAK PANGOLAT..BATAK PANONGONAN +1C24..1C2B ; Mc # [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU +1C34..1C35 ; Mc # [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG +1CE1 ; Mc # VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA +1CF2..1CF3 ; Mc # [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA +302E..302F ; Mc # [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK +A823..A824 ; Mc # [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I +A827 ; Mc # SYLOTI NAGRI VOWEL SIGN OO +A880..A881 ; Mc # [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA +A8B4..A8C3 ; Mc # [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU +A952..A953 ; Mc # [2] REJANG CONSONANT SIGN H..REJANG VIRAMA +A983 ; Mc # JAVANESE SIGN WIGNYAN +A9B4..A9B5 ; Mc # [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG +A9BA..A9BB ; Mc # [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE +A9BD..A9C0 ; Mc # [4] JAVANESE CONSONANT SIGN KERET..JAVANESE PANGKON +AA2F..AA30 ; Mc # [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI +AA33..AA34 ; Mc # [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA +AA4D ; Mc # CHAM CONSONANT SIGN FINAL H +AA7B ; Mc # MYANMAR SIGN PAO KAREN TONE +AA7D ; Mc # MYANMAR SIGN TAI LAING TONE-5 +AAEB ; Mc # MEETEI MAYEK VOWEL SIGN II +AAEE..AAEF ; Mc # [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU +AAF5 ; Mc # MEETEI MAYEK VOWEL SIGN VISARGA +ABE3..ABE4 ; Mc # [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP +ABE6..ABE7 ; Mc # [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP +ABE9..ABEA ; Mc # [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG +ABEC ; Mc # MEETEI MAYEK LUM IYEK +11000 ; Mc # BRAHMI SIGN CANDRABINDU +11002 ; Mc # BRAHMI SIGN VISARGA +11082 ; Mc # KAITHI SIGN VISARGA +110B0..110B2 ; Mc # [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II +110B7..110B8 ; Mc # [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU +1112C ; Mc # CHAKMA VOWEL SIGN E +11182 ; Mc # SHARADA SIGN VISARGA +111B3..111B5 ; Mc # [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II +111BF..111C0 ; Mc # [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA +1122C..1122E ; Mc # [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II +11232..11233 ; Mc # [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU +11235 ; Mc # KHOJKI SIGN VIRAMA +112E0..112E2 ; Mc # [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II +11302..11303 ; Mc # [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA +1133E..1133F ; Mc # [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I +11341..11344 ; Mc # [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR +11347..11348 ; Mc # [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI +1134B..1134D ; Mc # [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA +11357 ; Mc # GRANTHA AU LENGTH MARK +11362..11363 ; Mc # [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +11435..11437 ; Mc # [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II +11440..11441 ; Mc # [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU +11445 ; Mc # NEWA SIGN VISARGA +114B0..114B2 ; Mc # [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II +114B9 ; Mc # TIRHUTA VOWEL SIGN E +114BB..114BE ; Mc # [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU +114C1 ; Mc # TIRHUTA SIGN VISARGA +115AF..115B1 ; Mc # [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II +115B8..115BB ; Mc # [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU +115BE ; Mc # SIDDHAM SIGN VISARGA +11630..11632 ; Mc # [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II +1163B..1163C ; Mc # [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU +1163E ; Mc # MODI SIGN VISARGA +116AC ; Mc # TAKRI SIGN VISARGA +116AE..116AF ; Mc # [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II +116B6 ; Mc # TAKRI SIGN VIRAMA +11720..11721 ; Mc # [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA +11726 ; Mc # AHOM VOWEL SIGN E +11C2F ; Mc # BHAIKSUKI VOWEL SIGN AA +11C3E ; Mc # BHAIKSUKI SIGN VISARGA +11CA9 ; Mc # MARCHEN SUBJOINED LETTER YA +11CB1 ; Mc # MARCHEN VOWEL SIGN I +11CB4 ; Mc # MARCHEN VOWEL SIGN O +16F51..16F7E ; Mc # [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG +1D165..1D166 ; Mc # [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM +1D16D..1D172 ; Mc # [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 + +# Total code points: 394 + +# ================================================ + +# General_Category=Decimal_Number + +0030..0039 ; Nd # [10] DIGIT ZERO..DIGIT NINE +0660..0669 ; Nd # [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE +06F0..06F9 ; Nd # [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE +07C0..07C9 ; Nd # [10] NKO DIGIT ZERO..NKO DIGIT NINE +0966..096F ; Nd # [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE +09E6..09EF ; Nd # [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE +0A66..0A6F ; Nd # [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE +0AE6..0AEF ; Nd # [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE +0B66..0B6F ; Nd # [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE +0BE6..0BEF ; Nd # [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE +0C66..0C6F ; Nd # [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE +0CE6..0CEF ; Nd # [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE +0D66..0D6F ; Nd # [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE +0DE6..0DEF ; Nd # [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE +0E50..0E59 ; Nd # [10] THAI DIGIT ZERO..THAI DIGIT NINE +0ED0..0ED9 ; Nd # [10] LAO DIGIT ZERO..LAO DIGIT NINE +0F20..0F29 ; Nd # [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE +1040..1049 ; Nd # [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE +1090..1099 ; Nd # [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE +17E0..17E9 ; Nd # [10] KHMER DIGIT ZERO..KHMER DIGIT NINE +1810..1819 ; Nd # [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE +1946..194F ; Nd # [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE +19D0..19D9 ; Nd # [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE +1A80..1A89 ; Nd # [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE +1A90..1A99 ; Nd # [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE +1B50..1B59 ; Nd # [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE +1BB0..1BB9 ; Nd # [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE +1C40..1C49 ; Nd # [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE +1C50..1C59 ; Nd # [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE +A620..A629 ; Nd # [10] VAI DIGIT ZERO..VAI DIGIT NINE +A8D0..A8D9 ; Nd # [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE +A900..A909 ; Nd # [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE +A9D0..A9D9 ; Nd # [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE +A9F0..A9F9 ; Nd # [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE +AA50..AA59 ; Nd # [10] CHAM DIGIT ZERO..CHAM DIGIT NINE +ABF0..ABF9 ; Nd # [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE +FF10..FF19 ; Nd # [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE +104A0..104A9 ; Nd # [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE +11066..1106F ; Nd # [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE +110F0..110F9 ; Nd # [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE +11136..1113F ; Nd # [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE +111D0..111D9 ; Nd # [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE +112F0..112F9 ; Nd # [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE +11450..11459 ; Nd # [10] NEWA DIGIT ZERO..NEWA DIGIT NINE +114D0..114D9 ; Nd # [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE +11650..11659 ; Nd # [10] MODI DIGIT ZERO..MODI DIGIT NINE +116C0..116C9 ; Nd # [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE +11730..11739 ; Nd # [10] AHOM DIGIT ZERO..AHOM DIGIT NINE +118E0..118E9 ; Nd # [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE +11C50..11C59 ; Nd # [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE +16A60..16A69 ; Nd # [10] MRO DIGIT ZERO..MRO DIGIT NINE +16B50..16B59 ; Nd # [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE +1D7CE..1D7FF ; Nd # [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE +1E950..1E959 ; Nd # [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE + +# Total code points: 580 + +# ================================================ + +# General_Category=Letter_Number + +16EE..16F0 ; Nl # [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL +2160..2182 ; Nl # [35] ROMAN NUMERAL ONE..ROMAN NUMERAL TEN THOUSAND +2185..2188 ; Nl # [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND +3007 ; Nl # IDEOGRAPHIC NUMBER ZERO +3021..3029 ; Nl # [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE +3038..303A ; Nl # [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY +A6E6..A6EF ; Nl # [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM +10140..10174 ; Nl # [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS +10341 ; Nl # GOTHIC LETTER NINETY +1034A ; Nl # GOTHIC LETTER NINE HUNDRED +103D1..103D5 ; Nl # [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED +12400..1246E ; Nl # [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM + +# Total code points: 236 + +# ================================================ + +# General_Category=Other_Number + +00B2..00B3 ; No # [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE +00B9 ; No # SUPERSCRIPT ONE +00BC..00BE ; No # [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS +09F4..09F9 ; No # [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN +0B72..0B77 ; No # [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS +0BF0..0BF2 ; No # [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND +0C78..0C7E ; No # [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR +0D58..0D5E ; No # [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH +0D70..0D78 ; No # [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS +0F2A..0F33 ; No # [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO +1369..137C ; No # [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND +17F0..17F9 ; No # [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON +19DA ; No # NEW TAI LUE THAM DIGIT ONE +2070 ; No # SUPERSCRIPT ZERO +2074..2079 ; No # [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE +2080..2089 ; No # [10] SUBSCRIPT ZERO..SUBSCRIPT NINE +2150..215F ; No # [16] VULGAR FRACTION ONE SEVENTH..FRACTION NUMERATOR ONE +2189 ; No # VULGAR FRACTION ZERO THIRDS +2460..249B ; No # [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP +24EA..24FF ; No # [22] CIRCLED DIGIT ZERO..NEGATIVE CIRCLED DIGIT ZERO +2776..2793 ; No # [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN +2CFD ; No # COPTIC FRACTION ONE HALF +3192..3195 ; No # [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK +3220..3229 ; No # [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN +3248..324F ; No # [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE +3251..325F ; No # [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE +3280..3289 ; No # [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN +32B1..32BF ; No # [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY +A830..A835 ; No # [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS +10107..10133 ; No # [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND +10175..10178 ; No # [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN +1018A..1018B ; No # [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN +102E1..102FB ; No # [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED +10320..10323 ; No # [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY +10858..1085F ; No # [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND +10879..1087F ; No # [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY +108A7..108AF ; No # [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED +108FB..108FF ; No # [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED +10916..1091B ; No # [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE +109BC..109BD ; No # [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF +109C0..109CF ; No # [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY +109D2..109FF ; No # [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS +10A40..10A47 ; No # [8] KHAROSHTHI DIGIT ONE..KHAROSHTHI NUMBER ONE THOUSAND +10A7D..10A7E ; No # [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY +10A9D..10A9F ; No # [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY +10AEB..10AEF ; No # [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED +10B58..10B5F ; No # [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND +10B78..10B7F ; No # [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND +10BA9..10BAF ; No # [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED +10CFA..10CFF ; No # [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND +10E60..10E7E ; No # [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS +11052..11065 ; No # [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND +111E1..111F4 ; No # [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND +1173A..1173B ; No # [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY +118EA..118F2 ; No # [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY +11C5A..11C6C ; No # [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK +16B5B..16B61 ; No # [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS +1D360..1D371 ; No # [18] COUNTING ROD UNIT DIGIT ONE..COUNTING ROD TENS DIGIT NINE +1E8C7..1E8CF ; No # [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE +1F100..1F10C ; No # [13] DIGIT ZERO FULL STOP..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO + +# Total code points: 676 + +# ================================================ + +# General_Category=Space_Separator + +0020 ; Zs # SPACE +00A0 ; Zs # NO-BREAK SPACE +1680 ; Zs # OGHAM SPACE MARK +2000..200A ; Zs # [11] EN QUAD..HAIR SPACE +202F ; Zs # NARROW NO-BREAK SPACE +205F ; Zs # MEDIUM MATHEMATICAL SPACE +3000 ; Zs # IDEOGRAPHIC SPACE + +# Total code points: 17 + +# ================================================ + +# General_Category=Line_Separator + +2028 ; Zl # LINE SEPARATOR + +# Total code points: 1 + +# ================================================ + +# General_Category=Paragraph_Separator + +2029 ; Zp # PARAGRAPH SEPARATOR + +# Total code points: 1 + +# ================================================ + +# General_Category=Control + +0000..001F ; Cc # [32] <control-0000>..<control-001F> +007F..009F ; Cc # [33] <control-007F>..<control-009F> + +# Total code points: 65 + +# ================================================ + +# General_Category=Format + +00AD ; Cf # SOFT HYPHEN +0600..0605 ; Cf # [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE +061C ; Cf # ARABIC LETTER MARK +06DD ; Cf # ARABIC END OF AYAH +070F ; Cf # SYRIAC ABBREVIATION MARK +08E2 ; Cf # ARABIC DISPUTED END OF AYAH +180E ; Cf # MONGOLIAN VOWEL SEPARATOR +200B..200F ; Cf # [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK +202A..202E ; Cf # [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE +2060..2064 ; Cf # [5] WORD JOINER..INVISIBLE PLUS +2066..206F ; Cf # [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES +FEFF ; Cf # ZERO WIDTH NO-BREAK SPACE +FFF9..FFFB ; Cf # [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR +110BD ; Cf # KAITHI NUMBER SIGN +1BCA0..1BCA3 ; Cf # [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP +1D173..1D17A ; Cf # [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE +E0001 ; Cf # LANGUAGE TAG +E0020..E007F ; Cf # [96] TAG SPACE..CANCEL TAG + +# Total code points: 151 + +# ================================================ + +# General_Category=Private_Use + +E000..F8FF ; Co # [6400] <private-use-E000>..<private-use-F8FF> +F0000..FFFFD ; Co # [65534] <private-use-F0000>..<private-use-FFFFD> +100000..10FFFD; Co # [65534] <private-use-100000>..<private-use-10FFFD> + +# Total code points: 137468 + +# ================================================ + +# General_Category=Surrogate + +D800..DFFF ; Cs # [2048] <surrogate-D800>..<surrogate-DFFF> + +# Total code points: 2048 + +# ================================================ + +# General_Category=Dash_Punctuation + +002D ; Pd # HYPHEN-MINUS +058A ; Pd # ARMENIAN HYPHEN +05BE ; Pd # HEBREW PUNCTUATION MAQAF +1400 ; Pd # CANADIAN SYLLABICS HYPHEN +1806 ; Pd # MONGOLIAN TODO SOFT HYPHEN +2010..2015 ; Pd # [6] HYPHEN..HORIZONTAL BAR +2E17 ; Pd # DOUBLE OBLIQUE HYPHEN +2E1A ; Pd # HYPHEN WITH DIAERESIS +2E3A..2E3B ; Pd # [2] TWO-EM DASH..THREE-EM DASH +2E40 ; Pd # DOUBLE HYPHEN +301C ; Pd # WAVE DASH +3030 ; Pd # WAVY DASH +30A0 ; Pd # KATAKANA-HIRAGANA DOUBLE HYPHEN +FE31..FE32 ; Pd # [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH +FE58 ; Pd # SMALL EM DASH +FE63 ; Pd # SMALL HYPHEN-MINUS +FF0D ; Pd # FULLWIDTH HYPHEN-MINUS + +# Total code points: 24 + +# ================================================ + +# General_Category=Open_Punctuation + +0028 ; Ps # LEFT PARENTHESIS +005B ; Ps # LEFT SQUARE BRACKET +007B ; Ps # LEFT CURLY BRACKET +0F3A ; Ps # TIBETAN MARK GUG RTAGS GYON +0F3C ; Ps # TIBETAN MARK ANG KHANG GYON +169B ; Ps # OGHAM FEATHER MARK +201A ; Ps # SINGLE LOW-9 QUOTATION MARK +201E ; Ps # DOUBLE LOW-9 QUOTATION MARK +2045 ; Ps # LEFT SQUARE BRACKET WITH QUILL +207D ; Ps # SUPERSCRIPT LEFT PARENTHESIS +208D ; Ps # SUBSCRIPT LEFT PARENTHESIS +2308 ; Ps # LEFT CEILING +230A ; Ps # LEFT FLOOR +2329 ; Ps # LEFT-POINTING ANGLE BRACKET +2768 ; Ps # MEDIUM LEFT PARENTHESIS ORNAMENT +276A ; Ps # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT +276C ; Ps # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT +276E ; Ps # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT +2770 ; Ps # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT +2772 ; Ps # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT +2774 ; Ps # MEDIUM LEFT CURLY BRACKET ORNAMENT +27C5 ; Ps # LEFT S-SHAPED BAG DELIMITER +27E6 ; Ps # MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E8 ; Ps # MATHEMATICAL LEFT ANGLE BRACKET +27EA ; Ps # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EC ; Ps # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27EE ; Ps # MATHEMATICAL LEFT FLATTENED PARENTHESIS +2983 ; Ps # LEFT WHITE CURLY BRACKET +2985 ; Ps # LEFT WHITE PARENTHESIS +2987 ; Ps # Z NOTATION LEFT IMAGE BRACKET +2989 ; Ps # Z NOTATION LEFT BINDING BRACKET +298B ; Ps # LEFT SQUARE BRACKET WITH UNDERBAR +298D ; Ps # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298F ; Ps # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2991 ; Ps # LEFT ANGLE BRACKET WITH DOT +2993 ; Ps # LEFT ARC LESS-THAN BRACKET +2995 ; Ps # DOUBLE LEFT ARC GREATER-THAN BRACKET +2997 ; Ps # LEFT BLACK TORTOISE SHELL BRACKET +29D8 ; Ps # LEFT WIGGLY FENCE +29DA ; Ps # LEFT DOUBLE WIGGLY FENCE +29FC ; Ps # LEFT-POINTING CURVED ANGLE BRACKET +2E22 ; Ps # TOP LEFT HALF BRACKET +2E24 ; Ps # BOTTOM LEFT HALF BRACKET +2E26 ; Ps # LEFT SIDEWAYS U BRACKET +2E28 ; Ps # LEFT DOUBLE PARENTHESIS +2E42 ; Ps # DOUBLE LOW-REVERSED-9 QUOTATION MARK +3008 ; Ps # LEFT ANGLE BRACKET +300A ; Ps # LEFT DOUBLE ANGLE BRACKET +300C ; Ps # LEFT CORNER BRACKET +300E ; Ps # LEFT WHITE CORNER BRACKET +3010 ; Ps # LEFT BLACK LENTICULAR BRACKET +3014 ; Ps # LEFT TORTOISE SHELL BRACKET +3016 ; Ps # LEFT WHITE LENTICULAR BRACKET +3018 ; Ps # LEFT WHITE TORTOISE SHELL BRACKET +301A ; Ps # LEFT WHITE SQUARE BRACKET +301D ; Ps # REVERSED DOUBLE PRIME QUOTATION MARK +FD3F ; Ps # ORNATE RIGHT PARENTHESIS +FE17 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET +FE35 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS +FE37 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET +FE39 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET +FE3B ; Ps # PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET +FE3D ; Ps # PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET +FE3F ; Ps # PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET +FE41 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET +FE43 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET +FE47 ; Ps # PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET +FE59 ; Ps # SMALL LEFT PARENTHESIS +FE5B ; Ps # SMALL LEFT CURLY BRACKET +FE5D ; Ps # SMALL LEFT TORTOISE SHELL BRACKET +FF08 ; Ps # FULLWIDTH LEFT PARENTHESIS +FF3B ; Ps # FULLWIDTH LEFT SQUARE BRACKET +FF5B ; Ps # FULLWIDTH LEFT CURLY BRACKET +FF5F ; Ps # FULLWIDTH LEFT WHITE PARENTHESIS +FF62 ; Ps # HALFWIDTH LEFT CORNER BRACKET + +# Total code points: 75 + +# ================================================ + +# General_Category=Close_Punctuation + +0029 ; Pe # RIGHT PARENTHESIS +005D ; Pe # RIGHT SQUARE BRACKET +007D ; Pe # RIGHT CURLY BRACKET +0F3B ; Pe # TIBETAN MARK GUG RTAGS GYAS +0F3D ; Pe # TIBETAN MARK ANG KHANG GYAS +169C ; Pe # OGHAM REVERSED FEATHER MARK +2046 ; Pe # RIGHT SQUARE BRACKET WITH QUILL +207E ; Pe # SUPERSCRIPT RIGHT PARENTHESIS +208E ; Pe # SUBSCRIPT RIGHT PARENTHESIS +2309 ; Pe # RIGHT CEILING +230B ; Pe # RIGHT FLOOR +232A ; Pe # RIGHT-POINTING ANGLE BRACKET +2769 ; Pe # MEDIUM RIGHT PARENTHESIS ORNAMENT +276B ; Pe # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT +276D ; Pe # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT +276F ; Pe # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT +2771 ; Pe # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT +2773 ; Pe # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT +2775 ; Pe # MEDIUM RIGHT CURLY BRACKET ORNAMENT +27C6 ; Pe # RIGHT S-SHAPED BAG DELIMITER +27E7 ; Pe # MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E9 ; Pe # MATHEMATICAL RIGHT ANGLE BRACKET +27EB ; Pe # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27ED ; Pe # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EF ; Pe # MATHEMATICAL RIGHT FLATTENED PARENTHESIS +2984 ; Pe # RIGHT WHITE CURLY BRACKET +2986 ; Pe # RIGHT WHITE PARENTHESIS +2988 ; Pe # Z NOTATION RIGHT IMAGE BRACKET +298A ; Pe # Z NOTATION RIGHT BINDING BRACKET +298C ; Pe # RIGHT SQUARE BRACKET WITH UNDERBAR +298E ; Pe # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990 ; Pe # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2992 ; Pe # RIGHT ANGLE BRACKET WITH DOT +2994 ; Pe # RIGHT ARC GREATER-THAN BRACKET +2996 ; Pe # DOUBLE RIGHT ARC LESS-THAN BRACKET +2998 ; Pe # RIGHT BLACK TORTOISE SHELL BRACKET +29D9 ; Pe # RIGHT WIGGLY FENCE +29DB ; Pe # RIGHT DOUBLE WIGGLY FENCE +29FD ; Pe # RIGHT-POINTING CURVED ANGLE BRACKET +2E23 ; Pe # TOP RIGHT HALF BRACKET +2E25 ; Pe # BOTTOM RIGHT HALF BRACKET +2E27 ; Pe # RIGHT SIDEWAYS U BRACKET +2E29 ; Pe # RIGHT DOUBLE PARENTHESIS +3009 ; Pe # RIGHT ANGLE BRACKET +300B ; Pe # RIGHT DOUBLE ANGLE BRACKET +300D ; Pe # RIGHT CORNER BRACKET +300F ; Pe # RIGHT WHITE CORNER BRACKET +3011 ; Pe # RIGHT BLACK LENTICULAR BRACKET +3015 ; Pe # RIGHT TORTOISE SHELL BRACKET +3017 ; Pe # RIGHT WHITE LENTICULAR BRACKET +3019 ; Pe # RIGHT WHITE TORTOISE SHELL BRACKET +301B ; Pe # RIGHT WHITE SQUARE BRACKET +301E..301F ; Pe # [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK +FD3E ; Pe # ORNATE LEFT PARENTHESIS +FE18 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET +FE36 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS +FE38 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET +FE3A ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET +FE3C ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET +FE3E ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET +FE40 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET +FE42 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET +FE44 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET +FE48 ; Pe # PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET +FE5A ; Pe # SMALL RIGHT PARENTHESIS +FE5C ; Pe # SMALL RIGHT CURLY BRACKET +FE5E ; Pe # SMALL RIGHT TORTOISE SHELL BRACKET +FF09 ; Pe # FULLWIDTH RIGHT PARENTHESIS +FF3D ; Pe # FULLWIDTH RIGHT SQUARE BRACKET +FF5D ; Pe # FULLWIDTH RIGHT CURLY BRACKET +FF60 ; Pe # FULLWIDTH RIGHT WHITE PARENTHESIS +FF63 ; Pe # HALFWIDTH RIGHT CORNER BRACKET + +# Total code points: 73 + +# ================================================ + +# General_Category=Connector_Punctuation + +005F ; Pc # LOW LINE +203F..2040 ; Pc # [2] UNDERTIE..CHARACTER TIE +2054 ; Pc # INVERTED UNDERTIE +FE33..FE34 ; Pc # [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE +FE4D..FE4F ; Pc # [3] DASHED LOW LINE..WAVY LOW LINE +FF3F ; Pc # FULLWIDTH LOW LINE + +# Total code points: 10 + +# ================================================ + +# General_Category=Other_Punctuation + +0021..0023 ; Po # [3] EXCLAMATION MARK..NUMBER SIGN +0025..0027 ; Po # [3] PERCENT SIGN..APOSTROPHE +002A ; Po # ASTERISK +002C ; Po # COMMA +002E..002F ; Po # [2] FULL STOP..SOLIDUS +003A..003B ; Po # [2] COLON..SEMICOLON +003F..0040 ; Po # [2] QUESTION MARK..COMMERCIAL AT +005C ; Po # REVERSE SOLIDUS +00A1 ; Po # INVERTED EXCLAMATION MARK +00A7 ; Po # SECTION SIGN +00B6..00B7 ; Po # [2] PILCROW SIGN..MIDDLE DOT +00BF ; Po # INVERTED QUESTION MARK +037E ; Po # GREEK QUESTION MARK +0387 ; Po # GREEK ANO TELEIA +055A..055F ; Po # [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK +0589 ; Po # ARMENIAN FULL STOP +05C0 ; Po # HEBREW PUNCTUATION PASEQ +05C3 ; Po # HEBREW PUNCTUATION SOF PASUQ +05C6 ; Po # HEBREW PUNCTUATION NUN HAFUKHA +05F3..05F4 ; Po # [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM +0609..060A ; Po # [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN +060C..060D ; Po # [2] ARABIC COMMA..ARABIC DATE SEPARATOR +061B ; Po # ARABIC SEMICOLON +061E..061F ; Po # [2] ARABIC TRIPLE DOT PUNCTUATION MARK..ARABIC QUESTION MARK +066A..066D ; Po # [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR +06D4 ; Po # ARABIC FULL STOP +0700..070D ; Po # [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS +07F7..07F9 ; Po # [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK +0830..083E ; Po # [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU +085E ; Po # MANDAIC PUNCTUATION +0964..0965 ; Po # [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA +0970 ; Po # DEVANAGARI ABBREVIATION SIGN +0AF0 ; Po # GUJARATI ABBREVIATION SIGN +0DF4 ; Po # SINHALA PUNCTUATION KUNDDALIYA +0E4F ; Po # THAI CHARACTER FONGMAN +0E5A..0E5B ; Po # [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT +0F04..0F12 ; Po # [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD +0F14 ; Po # TIBETAN MARK GTER TSHEG +0F85 ; Po # TIBETAN MARK PALUTA +0FD0..0FD4 ; Po # [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA +0FD9..0FDA ; Po # [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS +104A..104F ; Po # [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE +10FB ; Po # GEORGIAN PARAGRAPH SEPARATOR +1360..1368 ; Po # [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR +166D..166E ; Po # [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP +16EB..16ED ; Po # [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION +1735..1736 ; Po # [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION +17D4..17D6 ; Po # [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH +17D8..17DA ; Po # [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT +1800..1805 ; Po # [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS +1807..180A ; Po # [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU +1944..1945 ; Po # [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK +1A1E..1A1F ; Po # [2] BUGINESE PALLAWA..BUGINESE END OF SECTION +1AA0..1AA6 ; Po # [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA +1AA8..1AAD ; Po # [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG +1B5A..1B60 ; Po # [7] BALINESE PANTI..BALINESE PAMENENG +1BFC..1BFF ; Po # [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT +1C3B..1C3F ; Po # [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK +1C7E..1C7F ; Po # [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD +1CC0..1CC7 ; Po # [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA +1CD3 ; Po # VEDIC SIGN NIHSHVASA +2016..2017 ; Po # [2] DOUBLE VERTICAL LINE..DOUBLE LOW LINE +2020..2027 ; Po # [8] DAGGER..HYPHENATION POINT +2030..2038 ; Po # [9] PER MILLE SIGN..CARET +203B..203E ; Po # [4] REFERENCE MARK..OVERLINE +2041..2043 ; Po # [3] CARET INSERTION POINT..HYPHEN BULLET +2047..2051 ; Po # [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY +2053 ; Po # SWUNG DASH +2055..205E ; Po # [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS +2CF9..2CFC ; Po # [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER +2CFE..2CFF ; Po # [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER +2D70 ; Po # TIFINAGH SEPARATOR MARK +2E00..2E01 ; Po # [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER +2E06..2E08 ; Po # [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER +2E0B ; Po # RAISED SQUARE +2E0E..2E16 ; Po # [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE +2E18..2E19 ; Po # [2] INVERTED INTERROBANG..PALM BRANCH +2E1B ; Po # TILDE WITH RING ABOVE +2E1E..2E1F ; Po # [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW +2E2A..2E2E ; Po # [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK +2E30..2E39 ; Po # [10] RING POINT..TOP HALF SECTION SIGN +2E3C..2E3F ; Po # [4] STENOGRAPHIC FULL STOP..CAPITULUM +2E41 ; Po # REVERSED COMMA +2E43..2E44 ; Po # [2] DASH WITH LEFT UPTURN..DOUBLE SUSPENSION MARK +3001..3003 ; Po # [3] IDEOGRAPHIC COMMA..DITTO MARK +303D ; Po # PART ALTERNATION MARK +30FB ; Po # KATAKANA MIDDLE DOT +A4FE..A4FF ; Po # [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP +A60D..A60F ; Po # [3] VAI COMMA..VAI QUESTION MARK +A673 ; Po # SLAVONIC ASTERISK +A67E ; Po # CYRILLIC KAVYKA +A6F2..A6F7 ; Po # [6] BAMUM NJAEMLI..BAMUM QUESTION MARK +A874..A877 ; Po # [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD +A8CE..A8CF ; Po # [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA +A8F8..A8FA ; Po # [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET +A8FC ; Po # DEVANAGARI SIGN SIDDHAM +A92E..A92F ; Po # [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA +A95F ; Po # REJANG SECTION MARK +A9C1..A9CD ; Po # [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH +A9DE..A9DF ; Po # [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN +AA5C..AA5F ; Po # [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA +AADE..AADF ; Po # [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI +AAF0..AAF1 ; Po # [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM +ABEB ; Po # MEETEI MAYEK CHEIKHEI +FE10..FE16 ; Po # [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK +FE19 ; Po # PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS +FE30 ; Po # PRESENTATION FORM FOR VERTICAL TWO DOT LEADER +FE45..FE46 ; Po # [2] SESAME DOT..WHITE SESAME DOT +FE49..FE4C ; Po # [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE +FE50..FE52 ; Po # [3] SMALL COMMA..SMALL FULL STOP +FE54..FE57 ; Po # [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK +FE5F..FE61 ; Po # [3] SMALL NUMBER SIGN..SMALL ASTERISK +FE68 ; Po # SMALL REVERSE SOLIDUS +FE6A..FE6B ; Po # [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT +FF01..FF03 ; Po # [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN +FF05..FF07 ; Po # [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE +FF0A ; Po # FULLWIDTH ASTERISK +FF0C ; Po # FULLWIDTH COMMA +FF0E..FF0F ; Po # [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS +FF1A..FF1B ; Po # [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON +FF1F..FF20 ; Po # [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT +FF3C ; Po # FULLWIDTH REVERSE SOLIDUS +FF61 ; Po # HALFWIDTH IDEOGRAPHIC FULL STOP +FF64..FF65 ; Po # [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT +10100..10102 ; Po # [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK +1039F ; Po # UGARITIC WORD DIVIDER +103D0 ; Po # OLD PERSIAN WORD DIVIDER +1056F ; Po # CAUCASIAN ALBANIAN CITATION MARK +10857 ; Po # IMPERIAL ARAMAIC SECTION SIGN +1091F ; Po # PHOENICIAN WORD SEPARATOR +1093F ; Po # LYDIAN TRIANGULAR MARK +10A50..10A58 ; Po # [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES +10A7F ; Po # OLD SOUTH ARABIAN NUMERIC INDICATOR +10AF0..10AF6 ; Po # [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER +10B39..10B3F ; Po # [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION +10B99..10B9C ; Po # [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT +11047..1104D ; Po # [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS +110BB..110BC ; Po # [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN +110BE..110C1 ; Po # [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA +11140..11143 ; Po # [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK +11174..11175 ; Po # [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK +111C5..111C9 ; Po # [5] SHARADA DANDA..SHARADA SANDHI MARK +111CD ; Po # SHARADA SUTRA MARK +111DB ; Po # SHARADA SIGN SIDDHAM +111DD..111DF ; Po # [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2 +11238..1123D ; Po # [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN +112A9 ; Po # MULTANI SECTION MARK +1144B..1144F ; Po # [5] NEWA DANDA..NEWA ABBREVIATION SIGN +1145B ; Po # NEWA PLACEHOLDER MARK +1145D ; Po # NEWA INSERTION SIGN +114C6 ; Po # TIRHUTA ABBREVIATION SIGN +115C1..115D7 ; Po # [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES +11641..11643 ; Po # [3] MODI DANDA..MODI ABBREVIATION SIGN +11660..1166C ; Po # [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT +1173C..1173E ; Po # [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI +11C41..11C45 ; Po # [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2 +11C70..11C71 ; Po # [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD +12470..12474 ; Po # [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON +16A6E..16A6F ; Po # [2] MRO DANDA..MRO DOUBLE DANDA +16AF5 ; Po # BASSA VAH FULL STOP +16B37..16B3B ; Po # [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM +16B44 ; Po # PAHAWH HMONG SIGN XAUS +1BC9F ; Po # DUPLOYAN PUNCTUATION CHINOOK FULL STOP +1DA87..1DA8B ; Po # [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS +1E95E..1E95F ; Po # [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK + +# Total code points: 544 + +# ================================================ + +# General_Category=Math_Symbol + +002B ; Sm # PLUS SIGN +003C..003E ; Sm # [3] LESS-THAN SIGN..GREATER-THAN SIGN +007C ; Sm # VERTICAL LINE +007E ; Sm # TILDE +00AC ; Sm # NOT SIGN +00B1 ; Sm # PLUS-MINUS SIGN +00D7 ; Sm # MULTIPLICATION SIGN +00F7 ; Sm # DIVISION SIGN +03F6 ; Sm # GREEK REVERSED LUNATE EPSILON SYMBOL +0606..0608 ; Sm # [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY +2044 ; Sm # FRACTION SLASH +2052 ; Sm # COMMERCIAL MINUS SIGN +207A..207C ; Sm # [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN +208A..208C ; Sm # [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN +2118 ; Sm # SCRIPT CAPITAL P +2140..2144 ; Sm # [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y +214B ; Sm # TURNED AMPERSAND +2190..2194 ; Sm # [5] LEFTWARDS ARROW..LEFT RIGHT ARROW +219A..219B ; Sm # [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE +21A0 ; Sm # RIGHTWARDS TWO HEADED ARROW +21A3 ; Sm # RIGHTWARDS ARROW WITH TAIL +21A6 ; Sm # RIGHTWARDS ARROW FROM BAR +21AE ; Sm # LEFT RIGHT ARROW WITH STROKE +21CE..21CF ; Sm # [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE +21D2 ; Sm # RIGHTWARDS DOUBLE ARROW +21D4 ; Sm # LEFT RIGHT DOUBLE ARROW +21F4..22FF ; Sm # [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP +2320..2321 ; Sm # [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL +237C ; Sm # RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +239B..23B3 ; Sm # [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM +23DC..23E1 ; Sm # [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET +25B7 ; Sm # WHITE RIGHT-POINTING TRIANGLE +25C1 ; Sm # WHITE LEFT-POINTING TRIANGLE +25F8..25FF ; Sm # [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE +266F ; Sm # MUSIC SHARP SIGN +27C0..27C4 ; Sm # [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET +27C7..27E5 ; Sm # [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK +27F0..27FF ; Sm # [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW +2900..2982 ; Sm # [131] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..Z NOTATION TYPE COLON +2999..29D7 ; Sm # [63] DOTTED FENCE..BLACK HOURGLASS +29DC..29FB ; Sm # [32] INCOMPLETE INFINITY..TRIPLE PLUS +29FE..2AFF ; Sm # [258] TINY..N-ARY WHITE VERTICAL BAR +2B30..2B44 ; Sm # [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET +2B47..2B4C ; Sm # [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +FB29 ; Sm # HEBREW LETTER ALTERNATIVE PLUS SIGN +FE62 ; Sm # SMALL PLUS SIGN +FE64..FE66 ; Sm # [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN +FF0B ; Sm # FULLWIDTH PLUS SIGN +FF1C..FF1E ; Sm # [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN +FF5C ; Sm # FULLWIDTH VERTICAL LINE +FF5E ; Sm # FULLWIDTH TILDE +FFE2 ; Sm # FULLWIDTH NOT SIGN +FFE9..FFEC ; Sm # [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +1D6C1 ; Sm # MATHEMATICAL BOLD NABLA +1D6DB ; Sm # MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6FB ; Sm # MATHEMATICAL ITALIC NABLA +1D715 ; Sm # MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D735 ; Sm # MATHEMATICAL BOLD ITALIC NABLA +1D74F ; Sm # MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D76F ; Sm # MATHEMATICAL SANS-SERIF BOLD NABLA +1D789 ; Sm # MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D7A9 ; Sm # MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7C3 ; Sm # MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1EEF0..1EEF1 ; Sm # [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL + +# Total code points: 948 + +# ================================================ + +# General_Category=Currency_Symbol + +0024 ; Sc # DOLLAR SIGN +00A2..00A5 ; Sc # [4] CENT SIGN..YEN SIGN +058F ; Sc # ARMENIAN DRAM SIGN +060B ; Sc # AFGHANI SIGN +09F2..09F3 ; Sc # [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN +09FB ; Sc # BENGALI GANDA MARK +0AF1 ; Sc # GUJARATI RUPEE SIGN +0BF9 ; Sc # TAMIL RUPEE SIGN +0E3F ; Sc # THAI CURRENCY SYMBOL BAHT +17DB ; Sc # KHMER CURRENCY SYMBOL RIEL +20A0..20BE ; Sc # [31] EURO-CURRENCY SIGN..LARI SIGN +A838 ; Sc # NORTH INDIC RUPEE MARK +FDFC ; Sc # RIAL SIGN +FE69 ; Sc # SMALL DOLLAR SIGN +FF04 ; Sc # FULLWIDTH DOLLAR SIGN +FFE0..FFE1 ; Sc # [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN +FFE5..FFE6 ; Sc # [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN + +# Total code points: 53 + +# ================================================ + +# General_Category=Modifier_Symbol + +005E ; Sk # CIRCUMFLEX ACCENT +0060 ; Sk # GRAVE ACCENT +00A8 ; Sk # DIAERESIS +00AF ; Sk # MACRON +00B4 ; Sk # ACUTE ACCENT +00B8 ; Sk # CEDILLA +02C2..02C5 ; Sk # [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD +02D2..02DF ; Sk # [14] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER CROSS ACCENT +02E5..02EB ; Sk # [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK +02ED ; Sk # MODIFIER LETTER UNASPIRATED +02EF..02FF ; Sk # [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW +0375 ; Sk # GREEK LOWER NUMERAL SIGN +0384..0385 ; Sk # [2] GREEK TONOS..GREEK DIALYTIKA TONOS +1FBD ; Sk # GREEK KORONIS +1FBF..1FC1 ; Sk # [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI +1FCD..1FCF ; Sk # [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI +1FDD..1FDF ; Sk # [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI +1FED..1FEF ; Sk # [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA +1FFD..1FFE ; Sk # [2] GREEK OXIA..GREEK DASIA +309B..309C ; Sk # [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +A700..A716 ; Sk # [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR +A720..A721 ; Sk # [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE +A789..A78A ; Sk # [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN +AB5B ; Sk # MODIFIER BREVE WITH INVERTED BREVE +FBB2..FBC1 ; Sk # [16] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL SMALL TAH BELOW +FF3E ; Sk # FULLWIDTH CIRCUMFLEX ACCENT +FF40 ; Sk # FULLWIDTH GRAVE ACCENT +FFE3 ; Sk # FULLWIDTH MACRON +1F3FB..1F3FF ; Sk # [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 + +# Total code points: 121 + +# ================================================ + +# General_Category=Other_Symbol + +00A6 ; So # BROKEN BAR +00A9 ; So # COPYRIGHT SIGN +00AE ; So # REGISTERED SIGN +00B0 ; So # DEGREE SIGN +0482 ; So # CYRILLIC THOUSANDS SIGN +058D..058E ; So # [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN +060E..060F ; So # [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA +06DE ; So # ARABIC START OF RUB EL HIZB +06E9 ; So # ARABIC PLACE OF SAJDAH +06FD..06FE ; So # [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN +07F6 ; So # NKO SYMBOL OO DENNEN +09FA ; So # BENGALI ISSHAR +0B70 ; So # ORIYA ISSHAR +0BF3..0BF8 ; So # [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN +0BFA ; So # TAMIL NUMBER SIGN +0C7F ; So # TELUGU SIGN TUUMU +0D4F ; So # MALAYALAM SIGN PARA +0D79 ; So # MALAYALAM DATE MARK +0F01..0F03 ; So # [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA +0F13 ; So # TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN +0F15..0F17 ; So # [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS +0F1A..0F1F ; So # [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG +0F34 ; So # TIBETAN MARK BSDUS RTAGS +0F36 ; So # TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN +0F38 ; So # TIBETAN MARK CHE MGO +0FBE..0FC5 ; So # [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE +0FC7..0FCC ; So # [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL +0FCE..0FCF ; So # [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM +0FD5..0FD8 ; So # [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS +109E..109F ; So # [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION +1390..1399 ; So # [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT +1940 ; So # LIMBU SIGN LOO +19DE..19FF ; So # [34] NEW TAI LUE SIGN LAE..KHMER SYMBOL DAP-PRAM ROC +1B61..1B6A ; So # [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE +1B74..1B7C ; So # [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING +2100..2101 ; So # [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT +2103..2106 ; So # [4] DEGREE CELSIUS..CADA UNA +2108..2109 ; So # [2] SCRUPLE..DEGREE FAHRENHEIT +2114 ; So # L B BAR SYMBOL +2116..2117 ; So # [2] NUMERO SIGN..SOUND RECORDING COPYRIGHT +211E..2123 ; So # [6] PRESCRIPTION TAKE..VERSICLE +2125 ; So # OUNCE SIGN +2127 ; So # INVERTED OHM SIGN +2129 ; So # TURNED GREEK SMALL LETTER IOTA +212E ; So # ESTIMATED SYMBOL +213A..213B ; So # [2] ROTATED CAPITAL Q..FACSIMILE SIGN +214A ; So # PROPERTY LINE +214C..214D ; So # [2] PER SIGN..AKTIESELSKAB +214F ; So # SYMBOL FOR SAMARITAN SOURCE +218A..218B ; So # [2] TURNED DIGIT TWO..TURNED DIGIT THREE +2195..2199 ; So # [5] UP DOWN ARROW..SOUTH WEST ARROW +219C..219F ; So # [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW +21A1..21A2 ; So # [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL +21A4..21A5 ; So # [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR +21A7..21AD ; So # [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW +21AF..21CD ; So # [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE +21D0..21D1 ; So # [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW +21D3 ; So # DOWNWARDS DOUBLE ARROW +21D5..21F3 ; So # [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW +2300..2307 ; So # [8] DIAMETER SIGN..WAVY LINE +230C..231F ; So # [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER +2322..2328 ; So # [7] FROWN..KEYBOARD +232B..237B ; So # [81] ERASE TO THE LEFT..NOT CHECK MARK +237D..239A ; So # [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL +23B4..23DB ; So # [40] TOP SQUARE BRACKET..FUSE +23E2..23FE ; So # [29] WHITE TRAPEZIUM..POWER SLEEP SYMBOL +2400..2426 ; So # [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO +2440..244A ; So # [11] OCR HOOK..OCR DOUBLE BACKSLASH +249C..24E9 ; So # [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z +2500..25B6 ; So # [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE +25B8..25C0 ; So # [9] BLACK RIGHT-POINTING SMALL TRIANGLE..BLACK LEFT-POINTING TRIANGLE +25C2..25F7 ; So # [54] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE CIRCLE WITH UPPER RIGHT QUADRANT +2600..266E ; So # [111] BLACK SUN WITH RAYS..MUSIC NATURAL SIGN +2670..2767 ; So # [248] WEST SYRIAC CROSS..ROTATED FLORAL HEART BULLET +2794..27BF ; So # [44] HEAVY WIDE-HEADED RIGHTWARDS ARROW..DOUBLE CURLY LOOP +2800..28FF ; So # [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678 +2B00..2B2F ; So # [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE +2B45..2B46 ; So # [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW +2B4D..2B73 ; So # [39] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR +2B76..2B95 ; So # [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW +2B98..2BB9 ; So # [34] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..UP ARROWHEAD IN A RECTANGLE BOX +2BBD..2BC8 ; So # [12] BALLOT BOX WITH LIGHT X..BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED +2BCA..2BD1 ; So # [8] TOP HALF BLACK CIRCLE..UNCERTAINTY SIGN +2BEC..2BEF ; So # [4] LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS..DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS +2CE5..2CEA ; So # [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA +2E80..2E99 ; So # [26] CJK RADICAL REPEAT..CJK RADICAL RAP +2E9B..2EF3 ; So # [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE +2F00..2FD5 ; So # [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE +2FF0..2FFB ; So # [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID +3004 ; So # JAPANESE INDUSTRIAL STANDARD SYMBOL +3012..3013 ; So # [2] POSTAL MARK..GETA MARK +3020 ; So # POSTAL MARK FACE +3036..3037 ; So # [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL +303E..303F ; So # [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE +3190..3191 ; So # [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK +3196..319F ; So # [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK +31C0..31E3 ; So # [36] CJK STROKE T..CJK STROKE Q +3200..321E ; So # [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU +322A..3247 ; So # [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO +3250 ; So # PARTNERSHIP SIGN +3260..327F ; So # [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL +328A..32B0 ; So # [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT +32C0..32FE ; So # [63] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..CIRCLED KATAKANA WO +3300..33FF ; So # [256] SQUARE APAATO..SQUARE GAL +4DC0..4DFF ; So # [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION +A490..A4C6 ; So # [55] YI RADICAL QOT..YI RADICAL KE +A828..A82B ; So # [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4 +A836..A837 ; So # [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK +A839 ; So # NORTH INDIC QUANTITY MARK +AA77..AA79 ; So # [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO +FDFD ; So # ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM +FFE4 ; So # FULLWIDTH BROKEN BAR +FFE8 ; So # HALFWIDTH FORMS LIGHT VERTICAL +FFED..FFEE ; So # [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE +FFFC..FFFD ; So # [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHARACTER +10137..1013F ; So # [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT +10179..10189 ; So # [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN +1018C..1018E ; So # [3] GREEK SINUSOID SIGN..NOMISMA SIGN +10190..1019B ; So # [12] ROMAN SEXTANS SIGN..ROMAN CENTURIAL SIGN +101A0 ; So # GREEK SYMBOL TAU RHO +101D0..101FC ; So # [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND +10877..10878 ; So # [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON +10AC8 ; So # MANICHAEAN SIGN UD +1173F ; So # AHOM SYMBOL VI +16B3C..16B3F ; So # [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB +16B45 ; So # PAHAWH HMONG SIGN CIM TSOV ROG +1BC9C ; So # DUPLOYAN SIGN O WITH CROSS +1D000..1D0F5 ; So # [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO +1D100..1D126 ; So # [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 +1D129..1D164 ; So # [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D16A..1D16C ; So # [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 +1D183..1D184 ; So # [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN +1D18C..1D1A9 ; So # [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH +1D1AE..1D1E8 ; So # [59] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KIEVAN FLAT SIGN +1D200..1D241 ; So # [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 +1D245 ; So # GREEK MUSICAL LEIMMA +1D300..1D356 ; So # [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING +1D800..1D9FF ; So # [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD +1DA37..1DA3A ; So # [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE +1DA6D..1DA74 ; So # [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING +1DA76..1DA83 ; So # [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH +1DA85..1DA86 ; So # [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS +1F000..1F02B ; So # [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK +1F030..1F093 ; So # [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 +1F0A0..1F0AE ; So # [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES +1F0B1..1F0BF ; So # [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER +1F0C1..1F0CF ; So # [15] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD BLACK JOKER +1F0D1..1F0F5 ; So # [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21 +1F110..1F12E ; So # [31] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED WZ +1F130..1F16B ; So # [60] SQUARED LATIN CAPITAL LETTER A..RAISED MD SIGN +1F170..1F1AC ; So # [61] NEGATIVE SQUARED LATIN CAPITAL LETTER A..SQUARED VOD +1F1E6..1F202 ; So # [29] REGIONAL INDICATOR SYMBOL LETTER A..SQUARED KATAKANA SA +1F210..1F23B ; So # [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D +1F240..1F248 ; So # [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 +1F250..1F251 ; So # [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT +1F300..1F3FA ; So # [251] CYCLONE..AMPHORA +1F400..1F6D2 ; So # [723] RAT..SHOPPING TROLLEY +1F6E0..1F6EC ; So # [13] HAMMER AND WRENCH..AIRPLANE ARRIVING +1F6F0..1F6F6 ; So # [7] SATELLITE..CANOE +1F700..1F773 ; So # [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE +1F780..1F7D4 ; So # [85] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR +1F800..1F80B ; So # [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD +1F810..1F847 ; So # [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW +1F850..1F859 ; So # [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW +1F860..1F887 ; So # [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW +1F890..1F8AD ; So # [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS +1F910..1F91E ; So # [15] ZIPPER-MOUTH FACE..HAND WITH INDEX AND MIDDLE FINGERS CROSSED +1F920..1F927 ; So # [8] FACE WITH COWBOY HAT..SNEEZING FACE +1F930 ; So # PREGNANT WOMAN +1F933..1F93E ; So # [12] SELFIE..HANDBALL +1F940..1F94B ; So # [12] WILTED FLOWER..MARTIAL ARTS UNIFORM +1F950..1F95E ; So # [15] CROISSANT..PANCAKES +1F980..1F991 ; So # [18] CRAB..SQUID +1F9C0 ; So # CHEESE WEDGE + +# Total code points: 5777 + +# ================================================ + +# General_Category=Initial_Punctuation + +00AB ; Pi # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +2018 ; Pi # LEFT SINGLE QUOTATION MARK +201B..201C ; Pi # [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK +201F ; Pi # DOUBLE HIGH-REVERSED-9 QUOTATION MARK +2039 ; Pi # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +2E02 ; Pi # LEFT SUBSTITUTION BRACKET +2E04 ; Pi # LEFT DOTTED SUBSTITUTION BRACKET +2E09 ; Pi # LEFT TRANSPOSITION BRACKET +2E0C ; Pi # LEFT RAISED OMISSION BRACKET +2E1C ; Pi # LEFT LOW PARAPHRASE BRACKET +2E20 ; Pi # LEFT VERTICAL BAR WITH QUILL + +# Total code points: 12 + +# ================================================ + +# General_Category=Final_Punctuation + +00BB ; Pf # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +2019 ; Pf # RIGHT SINGLE QUOTATION MARK +201D ; Pf # RIGHT DOUBLE QUOTATION MARK +203A ; Pf # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +2E03 ; Pf # RIGHT SUBSTITUTION BRACKET +2E05 ; Pf # RIGHT DOTTED SUBSTITUTION BRACKET +2E0A ; Pf # RIGHT TRANSPOSITION BRACKET +2E0D ; Pf # RIGHT RAISED OMISSION BRACKET +2E1D ; Pf # RIGHT LOW PARAPHRASE BRACKET +2E21 ; Pf # RIGHT VERTICAL BAR WITH QUILL + +# Total code points: 10 + +# EOF
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/VerticalOrientation-16.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/VerticalOrientation-16.txt new file mode 100644 index 0000000..0e715b29 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/ucd/VerticalOrientation-16.txt
@@ -0,0 +1,1033 @@ +# VerticalOrientation-16.txt +# Date: 2016-07-23, 01:00:00 GMT [EM, KI, LI] +# © 2016 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of +# Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Note: This data file accompanies Revision 16 of Unicode Technical +# Report #50, which has the status of Proposed Update. The approved +# version of this data file will appear in the subsequent Revision 17. +# +# Vertical_Orientation (vo) Property +# +# This file defines the Vertical_Orientation property. The file is not +# formally part of the Unicode Character Database. +# +# For documentation, see Revision 16 of +# Unicode Technical Report #50: Unicode Vertical Text Layout, +# at http://www.unicode.org/reports/tr50/tr50-16.html +# +# The character repertoire of this revision is the repertoire of +# Unicode Version 9.0. +# +# The format of the file is two fields separated by a semicolon. +# Field 0: Unicode code point value or range of code point values in +# hexadecimal form +# Field 1: Vertical_Orientation property value, one of the following: +# U - Upright, the same orientation as in the code charts +# R - Rotated 90 degrees clockwise compared to the code charts +# Tu - Transformed typographically, with fallback to Upright +# Tr - Transformed typographically, with fallback to Rotated +# +# @missing: 0000..10FFFF; R + +0000..001F ; R +0020 ; R +0021 ; R +0022 ; R +0023 ; R +0024 ; R +0025 ; R +0026 ; R +0027 ; R +0028 ; R +0029 ; R +002A ; R +002B ; R +002C ; R +002D ; R +002E..005A ; R +005B ; R +005C ; R +005D ; R +005E ; R +005F ; R +0060..007A ; R +007B ; R +007C ; R +007D ; R +007E ; R +007F ; R +0080..009F ; R +00A0 ; R +00A1 ; R +00A2 ; R +00A3 ; R +00A4 ; R +00A5 ; R +00A6 ; R +00A7 ; U +00A8 ; R +00A9 ; U +00AA ; R +00AB ; R +00AC ; R +00AD ; R +00AE ; U +00AF ; R +00B0 ; R +00B1 ; U +00B2 ; R +00B3 ; R +00B4 ; R +00B5 ; R +00B6 ; R +00B7 ; R +00B8 ; R +00B9 ; R +00BA ; R +00BB ; R +00BC ; U +00BD ; U +00BE ; U +00BF ; R +00C0..00D6 ; R +00D7 ; U +00D8..00F6 ; R +00F7 ; U +00F8..00FF ; R +0100..017F ; R +0180..024F ; R +0250..02AF ; R +02B0..02E4 ; R +02E5 ; R +02E6 ; R +02E7 ; R +02E8 ; R +02E9 ; R +02EA ; U +02EB ; U +02EC..02FF ; R +0300..036F ; R +0370..03FF ; R +0400..04FF ; R +0500..052F ; R +0530..0589 ; R +058A ; R +058B..058C ; R +058D..058E ; R +058F ; R +0590..05BD ; R +05BE ; R +05BF..05FF ; R +0600..06FF ; R +0700..074F ; R +0750..077F ; R +0780..07BF ; R +07C0..07FF ; R +0800..083F ; R +0840..085F ; R +08A0..08FF ; R +0900..097F ; R +0980..09FF ; R +0A00..0A7F ; R +0A80..0AFF ; R +0B00..0B7F ; R +0B80..0BFF ; R +0C00..0C7F ; R +0C80..0CFF ; R +0D00..0D7F ; R +0D80..0DFF ; R +0E00..0E7F ; R +0E80..0EFF ; R +0F00..0FFF ; R +1000..109F ; R +10A0..10FF ; R +1100..11FF ; U +1200..137F ; R +1380..139F ; R +13A0..13FF ; R +1400 ; R +1401..167F ; U +1680..169F ; R +16A0..16FF ; R +1700..171F ; R +1720..173F ; R +1740..175F ; R +1760..177F ; R +1780..17FF ; R +1800..18AF ; R +18B0..18FF ; U +1900..194F ; R +1950..197F ; R +1980..19DF ; R +19E0..19FF ; R +1A00..1A1F ; R +1A20..1AAF ; R +1AB0..1AFF ; R +1B00..1B7F ; R +1B80..1BBF ; R +1BC0..1BFF ; R +1C00..1C4F ; R +1C50..1C7F ; R +1C80..1C8F ; R +1CC0..1CCF ; R +1CD0..1CFF ; R +1D00..1D7F ; R +1D80..1DBF ; R +1DC0..1DFF ; R +1E00..1EFF ; R +1F00..1FFF ; R +2000..200A ; R +200B..200F ; R +2010 ; R +2011 ; R +2012 ; R +2013 ; R +2014 ; R +2015 ; R +2016 ; U +2017 ; R +2018 ; R +2019 ; R +201A ; R +201B ; R +201C ; R +201D ; R +201E ; R +201F ; R +2020 ; U +2021 ; U +2022 ; R +2023 ; R +2024 ; R +2025 ; R +2026 ; R +2027 ; R +2028..2029 ; R +202A..202E ; R +202F ; R +2030 ; U +2031 ; U +2032 ; R +2033 ; R +2034 ; R +2035 ; R +2036 ; R +2037 ; R +2038 ; R +2039 ; R +203A ; R +203B ; U +203C ; U +203D ; R +203E ; R +203F ; R +2040 ; R +2041 ; R +2042 ; U +2043 ; R +2044 ; R +2045 ; R +2046 ; R +2047 ; U +2048 ; U +2049 ; U +204A ; R +204B ; R +204C ; R +204D ; R +204E ; R +204F ; R +2050 ; R +2051 ; U +2052 ; R +2053 ; R +2054 ; R +2055 ; R +2056 ; R +2057 ; R +2058 ; R +2059 ; R +205A ; R +205B ; R +205C ; R +205D ; R +205E ; R +205F ; R +2060..2064 ; R +2065 ; U +2066..2069 ; R +206A..206F ; R +2070..209F ; R +20A0..20AB ; R +20AC ; R +20AD..20CF ; R +20D0..20DC ; R +20DD..20E0 ; U +20E1 ; R +20E2..20E4 ; U +20E5..20FF ; R +2100 ; U +2101 ; U +2102 ; R +2103 ; U +2104 ; U +2105 ; U +2106 ; U +2107 ; U +2108 ; U +2109 ; U +210A ; R +210B ; R +210C ; R +210D ; R +210E ; R +210F ; U +2110 ; R +2111 ; R +2112 ; R +2113 ; U +2114 ; U +2115 ; R +2116 ; U +2117 ; U +2118 ; R +2119 ; R +211A ; R +211B ; R +211C ; R +211D ; R +211E ; U +211F ; U +2120 ; U +2121 ; U +2122 ; U +2123 ; U +2124 ; R +2125 ; U +2126 ; R +2127 ; U +2128 ; R +2129 ; U +212A ; R +212B ; R +212C ; R +212D ; R +212E ; U +212F ; R +2130 ; R +2131 ; R +2132 ; R +2133 ; R +2134 ; R +2135 ; U +2136 ; U +2137 ; U +2138 ; U +2139 ; U +213A ; U +213B ; U +213C ; U +213D ; U +213E ; U +213F ; U +2140 ; R +2141 ; R +2142 ; R +2143 ; R +2144 ; R +2145 ; U +2146 ; U +2147 ; U +2148 ; U +2149 ; U +214A ; U +214B ; R +214C ; U +214D ; U +214E ; R +214F ; U +2150..2189 ; U +218A..218B ; R +218C..218F ; U +2190..21FF ; R +2200..221D ; R +221E ; U +221F..2233 ; R +2234..2235 ; U +2236..22FF ; R +2300..2307 ; U +2308..230B ; R +230C..231F ; U +2320 ; R +2321 ; R +2322..2323 ; R +2324..2328 ; U +2329 ; Tr +232A ; Tr +232B ; U +232C..237C ; R +237D..239A ; U +239B..23B3 ; R +23B4..23B6 ; R +23B7..23B9 ; R +23BA..23BD ; R +23BE..23CD ; U +23CE ; R +23CF ; U +23D0 ; R +23D1..23DB ; U +23DC..23E1 ; R +23E2..23FF ; U +2400..2422 ; U +2423 ; R +2424..243F ; U +2440..245F ; U +2460..24FF ; U +2500..257F ; R +2580..259F ; R +25A0..25FF ; U +2600..2619 ; U +261A..261F ; R +2620..26FF ; U +2700..2767 ; U +2768..2775 ; R +2776..2793 ; U +2794..27BF ; R +27C0..27C4 ; R +27C5..27C6 ; R +27C7..27E5 ; R +27E6..27EF ; R +27F0..27FF ; R +2800..28FF ; R +2900..297F ; R +2980..2982 ; R +2983..2998 ; R +2999..29D7 ; R +29D8..29DB ; R +29DC..29FB ; R +29FC..29FD ; R +29FE..29FF ; R +2A00..2AFF ; R +2B00..2B11 ; R +2B12..2B2F ; U +2B30..2B4F ; R +2B50..2B59 ; U +2B5A..2BB7 ; R +2BB8..2BEB ; U +2BEC..2BEF ; R +2BF0..2BFF ; U +2C00..2C5F ; R +2C60..2C7F ; R +2C80..2CFF ; R +2D00..2D2F ; R +2D30..2D7F ; R +2D80..2DDF ; R +2DE0..2DFF ; R +2E00..2E16 ; R +2E17 ; R +2E18..2E19 ; R +2E1A ; R +2E1B..2E1F ; R +2E20..2E21 ; R +2E22..2E25 ; R +2E26..2E29 ; R +2E2A..2E39 ; R +2E3A ; R +2E3B ; R +2E3C..2E44 ; R +2E45..2E7F ; R +2E80..2EFF ; U +2F00..2FDF ; U +2FE0..2FEF ; U +2FF0..2FFF ; U +3000 ; U +3001 ; Tu +3002 ; Tu +3003 ; U +3004 ; U +3005 ; U +3006 ; U +3007 ; U +3008 ; Tr +3009 ; Tr +300A ; Tr +300B ; Tr +300C ; Tr +300D ; Tr +300E ; Tr +300F ; Tr +3010 ; Tr +3011 ; Tr +3012 ; U +3013 ; U +3014 ; Tr +3015 ; Tr +3016 ; Tr +3017 ; Tr +3018 ; Tr +3019 ; Tr +301A ; Tr +301B ; Tr +301C ; Tr +301D ; Tr +301E ; Tr +301F ; Tr +3020 ; U +3021 ; U +3022 ; U +3023 ; U +3024 ; U +3025 ; U +3026 ; U +3027 ; U +3028 ; U +3029 ; U +302A ; U +302B ; U +302C ; U +302D ; U +302E ; U +302F ; U +3030 ; Tr +3031 ; U +3032 ; U +3033 ; U +3034 ; U +3035 ; U +3036 ; U +3037 ; U +3038 ; U +3039 ; U +303A ; U +303B ; U +303C ; U +303D ; U +303E ; U +303F ; U +3040 ; U +3041 ; Tu +3042 ; U +3043 ; Tu +3044 ; U +3045 ; Tu +3046 ; U +3047 ; Tu +3048 ; U +3049 ; Tu +304A ; U +304B ; U +304C ; U +304D ; U +304E ; U +304F ; U +3050 ; U +3051 ; U +3052 ; U +3053 ; U +3054 ; U +3055 ; U +3056 ; U +3057 ; U +3058 ; U +3059 ; U +305A ; U +305B ; U +305C ; U +305D ; U +305E ; U +305F ; U +3060 ; U +3061 ; U +3062 ; U +3063 ; Tu +3064 ; U +3065 ; U +3066 ; U +3067 ; U +3068 ; U +3069 ; U +306A ; U +306B ; U +306C ; U +306D ; U +306E ; U +306F ; U +3070 ; U +3071 ; U +3072 ; U +3073 ; U +3074 ; U +3075 ; U +3076 ; U +3077 ; U +3078 ; U +3079 ; U +307A ; U +307B ; U +307C ; U +307D ; U +307E ; U +307F ; U +3080 ; U +3081 ; U +3082 ; U +3083 ; Tu +3084 ; U +3085 ; Tu +3086 ; U +3087 ; Tu +3088 ; U +3089 ; U +308A ; U +308B ; U +308C ; U +308D ; U +308E ; Tu +308F ; U +3090 ; U +3091 ; U +3092 ; U +3093 ; U +3094 ; U +3095 ; Tu +3096 ; Tu +3097 ; U +3098 ; U +3099 ; U +309A ; U +309B ; Tu +309C ; Tu +309D ; U +309E ; U +309F ; U +30A0 ; Tr +30A1 ; Tu +30A2 ; U +30A3 ; Tu +30A4 ; U +30A5 ; Tu +30A6 ; U +30A7 ; Tu +30A8 ; U +30A9 ; Tu +30AA ; U +30AB ; U +30AC ; U +30AD ; U +30AE ; U +30AF ; U +30B0 ; U +30B1 ; U +30B2 ; U +30B3 ; U +30B4 ; U +30B5 ; U +30B6 ; U +30B7 ; U +30B8 ; U +30B9 ; U +30BA ; U +30BB ; U +30BC ; U +30BD ; U +30BE ; U +30BF ; U +30C0 ; U +30C1 ; U +30C2 ; U +30C3 ; Tu +30C4 ; U +30C5 ; U +30C6 ; U +30C7 ; U +30C8 ; U +30C9 ; U +30CA ; U +30CB ; U +30CC ; U +30CD ; U +30CE ; U +30CF ; U +30D0 ; U +30D1 ; U +30D2 ; U +30D3 ; U +30D4 ; U +30D5 ; U +30D6 ; U +30D7 ; U +30D8 ; U +30D9 ; U +30DA ; U +30DB ; U +30DC ; U +30DD ; U +30DE ; U +30DF ; U +30E0 ; U +30E1 ; U +30E2 ; U +30E3 ; Tu +30E4 ; U +30E5 ; Tu +30E6 ; U +30E7 ; Tu +30E8 ; U +30E9 ; U +30EA ; U +30EB ; U +30EC ; U +30ED ; U +30EE ; Tu +30EF ; U +30F0 ; U +30F1 ; U +30F2 ; U +30F3 ; U +30F4 ; U +30F5 ; Tu +30F6 ; Tu +30F7 ; U +30F8 ; U +30F9 ; U +30FA ; U +30FB ; U +30FC ; Tr +30FD ; U +30FE ; U +30FF ; U +3100..3126 ; U +3127 ; Tu +3128..312F ; U +3130..318F ; U +3190..319F ; U +31A0..31BF ; U +31C0..31EF ; U +31F0..31FF ; Tu +3200..321E ; U +321F..32FF ; U +3300..3357 ; Tu +3358..337A ; U +337B..337F ; Tu +3380..33FF ; U +3400..4DBF ; U +4DC0..4DFF ; U +4E00..9FFF ; U +A000..A48F ; U +A490..A4CF ; U +A4D0..A4FF ; R +A500..A63F ; R +A640..A69F ; R +A6A0..A6FF ; R +A700..A71F ; R +A720..A7FF ; R +A800..A82F ; R +A830..A83F ; R +A840..A87F ; R +A880..A8DF ; R +A8E0..A8FF ; R +A900..A92F ; R +A930..A95F ; R +A960..A97F ; U +A980..A9DF ; R +A9E0..A9FF ; R +AA00..AA5F ; R +AA60..AA7F ; R +AA80..AADF ; R +AAE0..AAFF ; R +AB00..AB2F ; R +AB30..AB6F ; R +AB70..ABBF ; R +ABC0..ABFF ; R +AC00..D7AF ; U +D7B0..D7FF ; U +D800..DFFF ; R +E000..F8FF ; U +F900..FAFF ; U +FB00..FB4F ; R +FB50..FDFF ; R +FE00..FE0F ; R +FE10 ; U +FE11 ; U +FE12 ; U +FE13 ; U +FE14 ; U +FE15 ; U +FE16 ; U +FE17 ; U +FE18 ; U +FE19 ; U +FE1A..FE1F ; U +FE20..FE2F ; R +FE30 ; U +FE31 ; U +FE32 ; U +FE33 ; U +FE34 ; U +FE35 ; U +FE36 ; U +FE37 ; U +FE38 ; U +FE39 ; U +FE3A ; U +FE3B ; U +FE3C ; U +FE3D ; U +FE3E ; U +FE3F ; U +FE40 ; U +FE41 ; U +FE42 ; U +FE43 ; U +FE44 ; U +FE45 ; U +FE46 ; U +FE47 ; U +FE48 ; U +FE49 ; R +FE4A ; R +FE4B ; R +FE4C ; R +FE4D ; R +FE4E ; R +FE4F ; R +FE50 ; Tu +FE51 ; Tu +FE52 ; Tu +FE53 ; U +FE54 ; U +FE55 ; U +FE56 ; U +FE57 ; U +FE58 ; R +FE59 ; Tr +FE5A ; Tr +FE5B ; Tr +FE5C ; Tr +FE5D ; Tr +FE5E ; Tr +FE5F ; U +FE60 ; U +FE61 ; U +FE62 ; U +FE63 ; R +FE64 ; R +FE65 ; R +FE66 ; R +FE67 ; U +FE68 ; U +FE69 ; U +FE6A ; U +FE6B ; U +FE6C..FE6F ; U +FE70..FEFF ; R +FF00 ; R +FF01 ; Tu +FF02 ; U +FF03 ; U +FF04 ; U +FF05 ; U +FF06 ; U +FF07 ; U +FF08 ; Tr +FF09 ; Tr +FF0A ; U +FF0B ; U +FF0C ; Tu +FF0D ; R +FF0E ; Tu +FF0F ; U +FF10 ; U +FF11 ; U +FF12 ; U +FF13 ; U +FF14 ; U +FF15 ; U +FF16 ; U +FF17 ; U +FF18 ; U +FF19 ; U +FF1A ; Tr +FF1B ; Tr +FF1C ; R +FF1D ; R +FF1E ; R +FF1F ; Tu +FF20 ; U +FF21..FF3A ; U +FF3B ; Tr +FF3C ; U +FF3D ; Tr +FF3E ; U +FF3F ; Tr +FF40 ; U +FF41..FF5A ; U +FF5B ; Tr +FF5C ; Tr +FF5D ; Tr +FF5E ; Tr +FF5F ; Tr +FF60 ; Tr +FF61 ; R +FF62 ; R +FF63 ; R +FF64 ; R +FF65 ; R +FF66 ; R +FF67 ; R +FF68 ; R +FF69 ; R +FF6A ; R +FF6B ; R +FF6C ; R +FF6D ; R +FF6E ; R +FF6F ; R +FF70 ; R +FF71..FF9F ; R +FFA0..FFDF ; R +FFE0 ; U +FFE1 ; U +FFE2 ; U +FFE3 ; Tr +FFE4 ; U +FFE5 ; U +FFE6 ; U +FFE7 ; U +FFE8 ; R +FFE9 ; R +FFEA ; R +FFEB ; R +FFEC ; R +FFED ; R +FFEE ; R +FFEF ; R +FFF0..FFF8 ; U +FFF9..FFFB ; R +FFFC ; U +FFFD ; U +FFFE ; R +FFFF ; R +10000..1007F ; R +10080..100FF ; R +10100..1013F ; R +10140..1018F ; R +10190..101CF ; R +101D0..101FF ; R +10280..1029F ; R +102A0..102DF ; R +102E0..102FF ; R +10300..1032F ; R +10330..1034F ; R +10350..1037F ; R +10380..1039F ; R +103A0..103DF ; R +10400..1044F ; R +10450..1047F ; R +10480..104AF ; R +104B0..104FF ; R +10500..1052F ; R +10530..1056F ; R +10600..1077F ; R +10800..1083F ; R +10840..1085F ; R +10860..1087F ; R +10880..108AF ; R +108E0..108FF ; R +10900..1091F ; R +10920..1093F ; R +10980..1099F ; U +109A0..109FF ; R +10A00..10A5F ; R +10A60..10A7F ; R +10A80..10A9F ; R +10AC0..10AFF ; R +10B00..10B3F ; R +10B40..10B5F ; R +10B60..10B7F ; R +10B80..10BAF ; R +10C00..10C4F ; R +10C80..10CFF ; R +10E60..10E7F ; R +11000..1107F ; R +11080..110CF ; R +110D0..110FF ; R +11100..1114F ; R +11150..1117F ; R +11180..111DF ; R +111E0..111FF ; R +11200..1124F ; R +11280..112AF ; R +112B0..112FF ; R +11300..1137F ; R +11400..1147F ; R +11480..114DF ; R +11580..115FF ; U +11600..1165F ; R +11660..1167F ; R +11680..116CF ; R +11700..1173F ; R +118A0..118FF ; R +11AC0..11AFF ; R +11C00..11C6F ; R +11C70..11CBF ; R +12000..123FF ; R +12400..1247F ; R +12480..1254F ; R +13000..1342F ; U +14400..1467F ; U +16800..16A3F ; R +16A40..16A6F ; R +16AD0..16AFF ; R +16B00..16B8F ; R +16F00..16F9F ; R +16FE0..16FFF ; U +17000..187FF ; U +18800..18AFF ; U +1B000..1B0FF ; U +1BC00..1BC9F ; R +1BCA0..1BCAF ; R +1D000..1D0FF ; U +1D100..1D1FF ; U +1D200..1D24F ; R +1D300..1D35F ; U +1D360..1D37F ; U +1D400..1D7FF ; R +1D800..1DAAF ; U +1E000..1E02F ; R +1E800..1E8DF ; R +1E900..1E95F ; R +1EE00..1EEFF ; R +1F000..1F02F ; U +1F030..1F09F ; U +1F0A0..1F0FF ; U +1F100..1F1FF ; U +1F200 ; Tu +1F201 ; Tu +1F202..1F2FF ; U +1F300..1F5FF ; U +1F600..1F64F ; U +1F650..1F67F ; U +1F680..1F6FF ; U +1F700..1F77F ; U +1F780..1F7FF ; U +1F800..1F8FF ; R +1F900..1F9FF ; U +20000..2A6DF ; U +2A6E0..2A6FF ; U +2A700..2B73F ; U +2B740..2B81F ; U +2B820..2CEAF ; U +2CEB0..2F7FF ; U +2F800..2FA1F ; U +2FA20..2FFFD ; U +30000..3FFFD ; U +E0000..E007F ; R +E0100..E01EF ; R +F0000..FFFFD ; U +100000..10FFFD ; U + +# EOF
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/unicode-data.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/unicode-data.js new file mode 100644 index 0000000..b3135a72 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes-3/tools/generators/unicode-data.js
@@ -0,0 +1,170 @@ +'use strict'; + +module.exports = (function () { + var fs = require("fs"); + var http = require("http"); + var path = require("path"); + var stream = require("stream"); + var url = require("url"); + + var unicodeData = { + url: { + blocks: "http://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt", + gc: "http://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt", + vo: "http://www.unicode.org/Public/vertical/revision-16/VerticalOrientation-16.txt", + }, + get: function (source, formatter) { + formatter = formatter || this.formatAsArray; + var buffer = ""; + var parser = new stream.Writable(); + parser._write = function (chunk, encoding, next) { + buffer += chunk; + next(); + }; + var promise = new Promise(function(resolve, reject) { + parser.on("finish", function () { + var results = null; + for (var line of buffer.split("\n")) + results = unicodeData.parseLine(line, formatter, results); + resolve(results); + }); + }); + var basename = path.basename(url.parse(source).path); + var local = "ucd/" + basename; + if (fs.existsSync(local)) { + fs.createReadStream(local) + .pipe(parser); + } else { + http.get(source, function (res) { + res.pipe(parser); + }); + } + return promise; + }, + copyToLocal: function () { + for (let key in unicodeData.url) { + let source = unicodeData.url[key]; + let basename = path.basename(url.parse(source).path); + let local = "ucd/" + basename; + console.log(`Copying ${key}: ${source} to ${local}`); + http.get(source, function (res) { + res.pipe(fs.createWriteStream(local)); + console.log(`Done ${key}: ${source} to ${local}`); + }); + } + }, + parseLine: function (line, formatter, results) { + if (!line.length || line[0] == "#") + return results; + var match = /([0-9A-F]+)(\.\.([0-9A-F]+))?\s*;\s*(\w+)/.exec(line); + if (!match) + throw new Error("Inavlid format: " + line); + var from = parseInt(match[1], 16); + var to = match[3] ? parseInt(match[3], 16) : from; + var value = match[4]; + return formatter(results, from, to, value); + }, + formatAsArray: function (results, from, to, value) { + results = results || []; + for (var code = from; code <= to; code++) + results[code] = value; + return results; + }, + formatAsRangesByValue: function (results, from, to, value) { + results = results || {}; + var list = results[value]; + if (!list) { + list = []; + results[value] = list; + } else { + var last = list[list.length - 1]; + if (last == from - 1) { + list[list.length - 1] = to; + return results; + } + } + list.push(from); + list.push(to); + return results; + }, + arrayFromRangesByValue: function (dict) { + var array = []; + for (var value in dict) { + var ranges = dict[value]; + for (var i = 0; i < ranges.length; i += 2) { + var to = ranges[i+1]; + for (var code = ranges[i]; code <= to; code++) + array[code] = value; + } + } + return array; + }, + isSkipGeneralCategory: function (code, gc) { + var gc0 = gc[code][0]; + // General Category M* and C* are omitted as they're likely to not render well + return gc0 == "M" || gc0 == "C"; + }, + isCJKMiddle: function (code) { + // To make tests smaller, omit some obvious ranges except the first and the last + return code > 0x3400 && code < 0x4DB5 || // CJK Unified Ideographs Extension A + code > 0x4E00 && code < 0x9FCC || // CJK Unified Ideographs (Han) + code > 0xAC00 && code < 0xD7A3 || // Hangul Syllables + code > 0x17000 && code < 0x187EC || // Tangut + code > 0x18800 && code < 0x18AF2 || // Tangut Components + code > 0x20000 && code < 0x2A6D6 || // CJK Unified Ideographs Extension B + code > 0x2A700 && code < 0x2B734 || // CJK Unified Ideographs Extension C + code > 0x2B740 && code < 0x2B81D || // CJK Unified Ideographs Extension D + code > 0x2B820 && code < 0x2CEA1; // CJK Unified Ideographs Extension E + }, + codePointsFromRanges: function (ranges, skipFunc) { + var codePoints = []; + for (var i = 0; i < ranges.length; i += 2) { + var code = ranges[i]; + var to = ranges[i+1]; + for (; code <= to; code++) { + if (code >= 0xD800 && code <= 0xDFFF) // Surrogate Pairs + continue; + if (skipFunc && skipFunc(code)) + continue; + codePoints.push(code); + } + } + return codePoints; + }, + splitCodePoints: function (codePoints, values) { + var results = []; + var currentCodePoints = []; + var currentValue = null; + for (var code of codePoints) { + var value = values[code]; + if (value != currentValue) { + results.push([currentCodePoints, currentValue]); + currentValue = value; + currentCodePoints = []; + } + currentCodePoints.push(code); + } + if (currentCodePoints.length) + results.push([currentCodePoints, currentValue]); + return results.slice(1); + }, + encodeUtf16: function (code, output) { + if (code >= 0x10000) { + code -= 0x10000; + output.push(code >>> 10 & 0x3FF | 0xD800); + code = 0xDC00 | code & 0x3FF; + } + output.push(code); + }, + toHex: function (value) { + return unicodeData.padZero(value.toString(16).toUpperCase(), 4); + }, + padZero: function (value, digits) { + if (value.length >= digits) + return value; + value = "0000" + value; + return value.substr(value.length - digits); + }, + }; + return unicodeData; +})();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html new file mode 100644 index 0000000..a3cc6d3d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01-ref.html
@@ -0,0 +1,9 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS test reference</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<style> +div { color: green; } +</style> +<div>This should be green</div> +<div>And this too</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html new file mode 100644 index 0000000..1a22ad4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/class-id-attr-selector-invalidation-01.html
@@ -0,0 +1,24 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: [id] and [class] attribute selectors are invalidated correctly.</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-selectors"> +<link rel="match" href="class-id-attr-selector-invalidation-01-ref.html"> +<style> +[class="foo"] { + color: green; +} +[id="baz"] { + color: green; +} +</style> +<div id="foo">This should be green</div> +<div id="bar">And this too</div> +<script> +onload = function() { + document.documentElement.offsetTop; + foo.classList.add("foo"); + bar.setAttribute("id", "baz"); + document.documentElement.offsetTop; +} +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-empty-args.html b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-empty-args.html new file mode 100644 index 0000000..8ffd68a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-empty-args.html
@@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<title>Check End Position of scrollIntoView when arg is not fully specified</title> +<div id="container" style="height: 2500px; width: 2500px;"> + <div id="content" style="height: 500px; width: 500px;margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;margin-bottom: 1000px;background-color: red"> + </div> +</div> +<script> +add_completion_callback(() => document.getElementById("container").remove()); +var content_height = 500; +var content_width = 500; +var window_height = document.documentElement.clientHeight; +var window_width = document.documentElement.clientWidth; +var content = document.getElementById("content"); + +function instantScrollToTestArgs(arg, expected_x, expected_y) { + window.scrollTo(0, 0); + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + if (arg == "omitted") + content.scrollIntoView(); + else + content.scrollIntoView(arg); + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); +} + +test(t => { + instantScrollToTestArgs("omitted", + content.offsetLeft + content_width - window_width, + content.offsetTop); + instantScrollToTestArgs(true, + content.offsetLeft + content_width - window_width, + content.offsetTop); + instantScrollToTestArgs(false, + content.offsetLeft + content_width - window_width, + content.offsetTop + content_height - window_height); + instantScrollToTestArgs({}, + content.offsetLeft + (content_width - window_width) / 2, + content.offsetTop + (content_height - window_height) / 2); + instantScrollToTestArgs(null, + content.offsetLeft + (content_width - window_width) / 2, + content.offsetTop + (content_height - window_height) / 2); + instantScrollToTestArgs(undefined, + content.offsetLeft + content_width - window_width, + content.offsetTop); +}, "scrollIntoView should behave correctly when the arg is not fully specified as ScrollIntoViewOptions"); + +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-shadow.html b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-shadow.html new file mode 100644 index 0000000..f272924 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-shadow.html
@@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<title>Check End Position of scrollIntoView of shadow elements</title> +<div id="container"> + <div id="space1" style="height: 2000px; width: 2000px;background-color: yellow"> + </div> + <div id="shadow"></div> + <div id="space2" style="height: 2000px; width: 2000px;background-color: blue"> + </div> +</div> +<script> +add_completion_callback(() => document.getElementById("container").remove()); + +test(t => { + var shadow = document.getElementById("shadow"); + var shadowRoot = shadow.createShadowRoot(); + var shadowDiv = document.createElement("div"); + shadowDiv.style.height = "200px"; + shadowDiv.style.width = "200px"; + shadowDiv.style.backgroundColor = "green"; + shadowRoot.appendChild(shadowDiv); + + window.scrollTo(0, 0); + var expected_x = shadowDiv.offsetLeft; + var expected_y = shadowDiv.offsetTop; + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + shadowDiv.scrollIntoView({block: "start", inlinePosition: "start"}); + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); +}, "scrollIntoView should behave correctly if applies to shadow dom elements"); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-smooth.html b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-smooth.html new file mode 100644 index 0000000..7a8b6a78 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cssom-view/scrollIntoView-smooth.html
@@ -0,0 +1,101 @@ +<!DOCTYPE HTML> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<title>Check End Position of smooth scrollIntoView</title> +<div id="container" style="height: 2500px; width: 2500px;"> + <div id="content" style="height: 500px; width: 500px;margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;margin-bottom: 1000px;background-color: red"> + </div> + <div id="shadow"></div> +</div> +<script> +var content_height = 500; +var content_width = 500; +var window_height = document.documentElement.clientHeight; +var window_width = document.documentElement.clientWidth; +var content = document.getElementById("content"); +add_completion_callback(() => document.getElementById("container").remove()); + +function waitForScrollEnd() { + var last_changed_frame = 0; + var last_x = window.scrollX; + var last_y = window.scrollY; + return new Promise((resolve, reject) => { + function tick(frames) { + // We requestAnimationFrame either for 500 frames or until 20 frames with + // no change have been observed. + if (frames >= 500 || frames - last_changed_frame > 20) { + resolve(); + } else { + if (window.scrollX != last_x || window.scrollY != last_y) { + last_changed_frame = frames; + last_x = window.scrollX; + last_y = window.scrollY; + } + requestAnimationFrame(tick.bind(null, frames + 1)); + } + } + tick(0); + }); +} + +// When testing manually, we need an additional frame at beginning +// to trigger the effect. +requestAnimationFrame(() => { +promise_test(t => { + window.scrollTo(0, 0); + var expected_x = content.offsetLeft + content_width - window_width; + var expected_y = content.offsetTop + content_height - window_height; + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + content.scrollIntoView({behavior: "smooth", block: "nearest", inlinePosition: +"nearest"}); + return waitForScrollEnd().then(() => { + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); + }); +}, "Smooth scrollIntoView should scroll the element to the 'nearest' position"); + +promise_test(t => { + window.scrollTo(0, 0); + var expected_x = content.offsetLeft; + var expected_y = content.offsetTop; + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + content.scrollIntoView({behavior: "smooth", block: "start", inlinePosition: +"start"}); + return waitForScrollEnd().then(() => { + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); + }); +}, "Smooth scrollIntoView should scroll the element to the 'start' position"); + +promise_test(t => { + window.scrollTo(0, 0); + var expected_x = content.offsetLeft + (content_width - window_width) / 2; + var expected_y = content.offsetTop + (content_height - window_height) / 2; + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + content.scrollIntoView({behavior: "smooth", block: "center", inlinePosition: +"center"}); + return waitForScrollEnd().then(() => { + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); + }); +}, "Smooth scrollIntoView should scroll the element to the 'center' position"); + +promise_test(t => { + window.scrollTo(0, 0); + var expected_x = content.offsetLeft + content_width - window_width; + var expected_y = content.offsetTop + content_height - window_height; + assert_not_equals(window.scrollX, expected_x); + assert_not_equals(window.scrollY, expected_y); + content.scrollIntoView({behavior: "smooth", block: "end", inlinePosition: +"end"}); + return waitForScrollEnd().then(() => { + assert_approx_equals(window.scrollX, expected_x, 1); + assert_approx_equals(window.scrollY, expected_y, 1); + }); +}, "Smooth scrollIntoView should scroll the element to the 'end' position"); + +}); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py new file mode 100644 index 0000000..5ba69f8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py
@@ -0,0 +1,55 @@ +from string import Template +import os +import sys + +template = Template("""<!DOCTYPE html> +<!-- This file is generated by $generator --> +<html> + <head> + <title>SVG sizing: <$placeholder></title> + <meta name=timeout content=long> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="../resources/svg-sizing.js"></script> + <style> + #testContainer { + position: absolute; + left: 0; + top: 0; + width: 800px; + height: 600px + } + iframe { border: 0 } + </style> + <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width"> + <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height"> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements"> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width"> + <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace"> + </head> + <body> + <div id="log"></div> + <div id="testContainer"></div> + <div id="demo"></div> + <script src="svg-embedded-sizing.js"></script> + <script>testPlaceholderWithHeight("$placeholder", $placeholderHeightAttr)</script> + </body> +</html> +""") + +placeholders = [ "object", "iframe", "img" ] +placeholderHeightAttrs = [ "null", "'100px'", "'100%'" ] +placeholderHeightAttrsDescriptions = [ "auto", "fixed", "percentage" ] + +try: + os.makedirs("../svg-embedded-sizing") +except OSError: + pass + +for placeholder in placeholders: + for i, placeholderHeightAttr in enumerate(placeholderHeightAttrs): + testContent = template.substitute(placeholder=placeholder, placeholderHeightAttr=placeholderHeightAttr, generator=sys.argv[0]) + filename = "../svg-embedded-sizing/svg-in-%s-%s.html" % (placeholder, placeholderHeightAttrsDescriptions[i]) + f = open(filename, "w") + f.write(testContent) + f.close()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html index 212ffc1..25de796 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-async-classic-script.html
@@ -17,12 +17,6 @@ window.onload = resolve; }); -waitForAsyncScript = () => { - return new Promise((resolve) => { - waitForLoadEvent.then(() => setTimeout(resolve, 200)); - }); -} - promise_test(() => { window.executed = false; let loaded = false; @@ -36,7 +30,7 @@ script.noModule = false; document.body.appendChild(script); - return waitForAsyncScript().then(() => { + return waitForLoadEvent.then(() => { assert_true(supportsNoModule); assert_true(executed); assert_true(loaded); @@ -56,7 +50,7 @@ script.noModule = true; document.body.appendChild(script); - return waitForAsyncScript().then(() => { + return waitForLoadEvent.then(() => { assert_true(supportsNoModule); assert_false(executed); assert_false(loaded);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html index 83c3c5a..9f6207c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/scripting-1/the-script-element/nomodule-set-on-synchronously-loaded-classic-scripts.html
@@ -36,11 +36,6 @@ assert_false(errored); }, 'A synchronously loaded external classic script with nomodule content attribute must not run'); - -waitForLoadEvent = new Promise((resolve) => { - window.onload = resolve; -}); - </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/tools/build.sh b/third_party/WebKit/LayoutTests/external/wpt/html/tools/build.sh new file mode 100755 index 0000000..4453604 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/tools/build.sh
@@ -0,0 +1,11 @@ +#!/usr/bin/env sh +set -ex + +cd "${0%/*}" +virtualenv -p python .virtualenv +.virtualenv/bin/pip install genshi +git clone https://github.com/html5lib/html5lib-python.git .virtualenv/html5lib && cd .virtualenv/html5lib || cd .virtualenv/html5lib && git pull +git submodule update --init --recursive +cd ../.. +.virtualenv/bin/pip install -e .virtualenv/html5lib +.virtualenv/bin/python update_html5lib_tests.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test.xml b/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test.xml new file mode 100644 index 0000000..8af4adc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test.xml
@@ -0,0 +1,29 @@ +<html xmlns:py="http://genshi.edgewall.org/"> + <head> + <meta charset="utf8"/> + <title>HTML 5 Parser tests ${file_name}</title> + <meta name="timeout" content="long"/> + <meta name="variant" content="?run_type=uri"/> + <meta name="variant" content="?run_type=write"/> + <meta name="variant" content="?run_type=write_single"/> + </head> + <body> + <h1>html5lib Parser Test</h1> + <div id="log"></div> + <script src="common.js"></script> + <script src="test.js"></script> + <script src="template.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script> + var num_iframes = 8; + + var order = [<py:for each="test in tests">'${test.id}',</py:for>]; + var tests = { + <py:for each="test in tests">"${test.id}":[async_test('${file_name} ${test.id}'), ${test.string_uri_encoded_input}, ${test.string_escaped_expected}],</py:for> + } + init_tests(get_type()); + </script> + + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test_fragment.xml b/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test_fragment.xml new file mode 100644 index 0000000..5be259b74 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/tools/html5lib_test_fragment.xml
@@ -0,0 +1,27 @@ +<html xmlns:py="http://genshi.edgewall.org/"> + <head> + <meta charset="utf8"/> + <title>HTML 5 Parser tests ${file_name}</title> + <meta name="timeout" content="long"/> + </head> + <body> + <h1>html5lib Parser Test</h1> + <div id="log"></div> + <script src="common.js"></script> + <script src="test.js"></script> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script> + + var num_iframes = 8; + + var order = [<py:for each="test in tests">'${test.id}',</py:for>]; + var tests = { + <py:for each="test in tests">"${test.id}":[async_test('${file_name} ${test.id}'), ${test.string_uri_encoded_input}, ${test.string_escaped_expected}, '${test.container}'],</py:for> + } + + init_tests("innerHTML"); + + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/tools/update_html5lib_tests.py b/third_party/WebKit/LayoutTests/external/wpt/html/tools/update_html5lib_tests.py new file mode 100644 index 0000000..2235ddf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/tools/update_html5lib_tests.py
@@ -0,0 +1,152 @@ +import sys +import os +import hashlib +import urllib +import itertools +import re +import json +import glob +import shutil + +try: + import genshi + from genshi.template import MarkupTemplate + + from html5lib.tests import support +except ImportError: + print """This script requires the Genshi templating library and html5lib source + +It is recommended that these are installed in a virtualenv: + +virtualenv venv +source venv/bin/activate +pip install genshi +cd venv +git clone git@github.com:html5lib/html5lib-python.git html5lib +cd html5lib +git submodule init +git submodule update +pip install -e ./ + +Then run this script again, with the virtual environment still active. +When you are done, type "deactivate" to deactivate the virtual environment. +""" + +TESTS_PATH = "html/syntax/parsing/" + +def get_paths(): + script_path = os.path.split(os.path.abspath(__file__))[0] + repo_base = get_repo_base(script_path) + tests_path = os.path.join(repo_base, TESTS_PATH) + return script_path, tests_path + +def get_repo_base(path): + while path: + if os.path.exists(os.path.join(path, ".git")): + return path + else: + path = os.path.split(path)[0] + +def get_expected(data): + data = "#document\n" + data + return data + +def get_hash(data, container=None): + if container == None: + container = "" + return hashlib.sha1("#container%s#data%s"%(container.encode("utf8"), + data.encode("utf8"))).hexdigest() + +def make_tests(script_dir, out_dir, input_file_name, test_data): + tests = [] + innerHTML_tests = [] + ids_seen = {} + print input_file_name + for test in test_data: + if "script-off" in test: + continue + is_innerHTML = "document-fragment" in test + data = test["data"] + container = test["document-fragment"] if is_innerHTML else None + assert test["document"], test + expected = get_expected(test["document"]) + test_list = innerHTML_tests if is_innerHTML else tests + test_id = get_hash(data, container) + if test_id in ids_seen: + print "WARNING: id %s seen multiple times in file %s this time for test (%s, %s) before for test %s, skipping"%(test_id, input_file_name, container, data, ids_seen[test_id]) + continue + ids_seen[test_id] = (container, data) + test_list.append({'string_uri_encoded_input':"\"%s\""%urllib.quote(data.encode("utf8")), + 'input':data, + 'expected':expected, + 'string_escaped_expected':json.dumps(urllib.quote(expected.encode("utf8"))), + 'id':test_id, + 'container':container + }) + path_normal = None + if tests: + path_normal = write_test_file(script_dir, out_dir, + tests, "html5lib_%s"%input_file_name, + "html5lib_test.xml") + path_innerHTML = None + if innerHTML_tests: + path_innerHTML = write_test_file(script_dir, out_dir, + innerHTML_tests, "html5lib_innerHTML_%s"%input_file_name, + "html5lib_test_fragment.xml") + + return path_normal, path_innerHTML + +def write_test_file(script_dir, out_dir, tests, file_name, template_file_name): + file_name = os.path.join(out_dir, file_name + ".html") + short_name = os.path.split(file_name)[1] + + with open(os.path.join(script_dir, template_file_name), "r") as f: + template = MarkupTemplate(f) + + stream = template.generate(file_name=short_name, tests=tests) + + with open(file_name, "w") as f: + f.write(stream.render('html', doctype='html5', + encoding="utf8")) + return file_name + +def escape_js_string(in_data): + return in_data.encode("utf8").encode("string-escape") + +def serialize_filenames(test_filenames): + return "[" + ",\n".join("\"%s\""%item for item in test_filenames) + "]" + +def main(): + + script_dir, out_dir = get_paths() + + test_files = [] + inner_html_files = [] + + if len(sys.argv) > 2: + test_iterator = itertools.izip( + itertools.repeat(False), + sorted(os.path.abspath(item) for item in + glob.glob(os.path.join(sys.argv[2], "*.dat")))) + else: + test_iterator = itertools.chain( + itertools.izip(itertools.repeat(False), + sorted(support.get_data_files("tree-construction"))), + itertools.izip(itertools.repeat(True), + sorted(support.get_data_files( + os.path.join("tree-construction", "scripted"))))) + + for (scripted, test_file) in test_iterator: + input_file_name = os.path.splitext(os.path.split(test_file)[1])[0] + if scripted: + input_file_name = "scripted_" + input_file_name + test_data = support.TestData(test_file) + test_filename, inner_html_file_name = make_tests(script_dir, out_dir, + input_file_name, test_data) + if test_filename is not None: + test_files.append(test_filename) + if inner_html_file_name is not None: + inner_html_files.append(inner_html_file_name) + +if __name__ == "__main__": + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/__init__.py b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/__init__.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/clean.py b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/clean.py new file mode 100755 index 0000000..9416f0b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/clean.py
@@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import os, json +from common_paths import * +import spec_validator + +def rmtree(top): + top = os.path.abspath(top) + assert top != os.path.expanduser("~") + assert len(top) > len(os.path.expanduser("~")) + assert "web-platform-tests" in top + assert "mixed-content" in top + + for root, dirs, files in os.walk(top, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + + os.rmdir(top) + +def main(): + spec_json = load_spec_json(); + spec_validator.assert_valid_spec_json(spec_json) + + for spec in spec_json['specification']: + generated_dir = os.path.join(spec_directory, spec["name"]) + if (os.path.isdir(generated_dir)): + rmtree(generated_dir) + + if (os.path.isfile(generated_spec_json_filename)): + os.remove(generated_spec_json_filename) + +if __name__ == '__main__': + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/common_paths.py b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/common_paths.py new file mode 100644 index 0000000..5c2807d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/common_paths.py
@@ -0,0 +1,58 @@ +import os, sys, json, re + +script_directory = os.path.dirname(os.path.abspath(__file__)) +generic_directory = os.path.abspath(os.path.join(script_directory, '..')) + +template_directory = os.path.abspath(os.path.join(script_directory, + '..', + 'template')) +spec_directory = os.path.abspath(os.path.join(script_directory, '..', '..')) +test_root_directory = os.path.abspath(os.path.join(script_directory, + '..', '..', '..')) + +spec_filename = os.path.join(spec_directory, "spec.src.json") +generated_spec_json_filename = os.path.join(spec_directory, "spec_json.js") + +selection_pattern = '%(opt_in_method)s/' + \ + '%(origin)s/' + \ + '%(subresource)s/' + \ + '%(context_nesting)s/' + \ + '%(redirection)s/' + +test_file_path_pattern = '%(spec_name)s/' + selection_pattern + \ + '%(name)s.%(source_scheme)s.html' + + +def get_template(basename): + with open(os.path.join(template_directory, basename), "r") as f: + return f.read() + + +def write_file(filename, contents): + with open(filename, "w") as f: + f.write(contents) + + +def read_nth_line(fp, line_number): + fp.seek(0) + for i, line in enumerate(fp): + if (i + 1) == line_number: + return line + + +def load_spec_json(path_to_spec = None): + if path_to_spec is None: + path_to_spec = spec_filename + + re_error_location = re.compile('line ([0-9]+) column ([0-9]+)') + with open(path_to_spec, "r") as f: + try: + return json.load(f) + except ValueError, ex: + print ex.message + match = re_error_location.search(ex.message) + if match: + line_number, column = int(match.group(1)), int(match.group(2)) + print read_nth_line(f, line_number).rstrip() + print " " * (column - 1) + "^" + sys.exit(1)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/generate.py b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/generate.py new file mode 100755 index 0000000..6dcaebd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/generate.py
@@ -0,0 +1,157 @@ +#!/usr/bin/env python + +import os, sys, json +from common_paths import * +import spec_validator +import argparse + + +def expand_pattern(expansion_pattern, test_expansion_schema): + expansion = {} + for artifact_key in expansion_pattern: + artifact_value = expansion_pattern[artifact_key] + if artifact_value == '*': + expansion[artifact_key] = test_expansion_schema[artifact_key] + elif isinstance(artifact_value, list): + expansion[artifact_key] = artifact_value + elif isinstance(artifact_value, dict): + # Flattened expansion. + expansion[artifact_key] = [] + values_dict = expand_pattern(artifact_value, + test_expansion_schema[artifact_key]) + for sub_key in values_dict.keys(): + expansion[artifact_key] += values_dict[sub_key] + else: + expansion[artifact_key] = [artifact_value] + + return expansion + + +def permute_expansion(expansion, artifact_order, selection = {}, artifact_index = 0): + assert isinstance(artifact_order, list), "artifact_order should be a list" + + if artifact_index >= len(artifact_order): + yield selection + return + + artifact_key = artifact_order[artifact_index] + + for artifact_value in expansion[artifact_key]: + selection[artifact_key] = artifact_value + for next_selection in permute_expansion(expansion, + artifact_order, + selection, + artifact_index + 1): + yield next_selection + + +def generate_selection(selection, spec, test_html_template_basename): + selection['spec_name'] = spec['name'] + selection['spec_title'] = spec['title'] + selection['spec_description'] = spec['description'] + selection['spec_specification_url'] = spec['specification_url'] + + test_filename = test_file_path_pattern % selection + test_headers_filename = test_filename + ".headers" + test_directory = os.path.dirname(test_filename) + full_path = os.path.join(spec_directory, test_directory) + + test_html_template = get_template(test_html_template_basename) + test_js_template = get_template("test.js.template") + disclaimer_template = get_template('disclaimer.template') + test_description_template = get_template("test_description.template") + + html_template_filename = os.path.join(template_directory, + test_html_template_basename) + generated_disclaimer = disclaimer_template \ + % {'generating_script_filename': os.path.relpath(__file__, + test_root_directory), + 'html_template_filename': os.path.relpath(html_template_filename, + test_root_directory)} + + selection['generated_disclaimer'] = generated_disclaimer.rstrip() + test_description_template = \ + test_description_template.rstrip().replace("\n", "\n" + " " * 33) + selection['test_description'] = test_description_template % selection + + # Adjust the template for the test invoking JS. Indent it to look nice. + indent = "\n" + " " * 6; + test_js_template = indent + test_js_template.replace("\n", indent); + selection['test_js'] = test_js_template % selection + + # Directory for the test files. + try: + os.makedirs(full_path) + except: + pass + + # TODO(kristijanburnik): Implement the opt-in-method here. + opt_in_method = selection['opt_in_method'] + selection['meta_opt_in'] = '' + if opt_in_method == 'meta-csp': + selection['meta_opt_in'] = '\n <meta http-equiv="Content-Security-Policy" ' + \ + 'content="block-all-mixed-content">' + elif opt_in_method == 'http-csp': + opt_in_headers = "Content-Security-Policy: block-all-mixed-content\n" + write_file(test_headers_filename, opt_in_headers) + elif opt_in_method == 'no-opt-in': + pass + else: + raise ValueError("Invalid opt_in_method %s" % opt_in_method) + + # Write out the generated HTML file. + write_file(test_filename, test_html_template % selection) + +def generate_test_source_files(spec_json, target): + test_expansion_schema = spec_json['test_expansion_schema'] + specification = spec_json['specification'] + + spec_json_js_template = get_template('spec_json.js.template') + write_file(generated_spec_json_filename, + spec_json_js_template % {'spec_json': json.dumps(spec_json)}) + + # Choose a debug/release template depending on the target. + html_template = "test.%s.html.template" % target + + artifact_order = test_expansion_schema.keys() + ['name'] + + # Create list of excluded tests. + exclusion_dict = {} + for excluded_pattern in spec_json['excluded_tests']: + excluded_expansion = \ + expand_pattern(excluded_pattern, + test_expansion_schema) + for excluded_selection in permute_expansion(excluded_expansion, artifact_order): + excluded_selection_path = selection_pattern % excluded_selection + exclusion_dict[excluded_selection_path] = True + + for spec in specification: + for expansion_pattern in spec['test_expansion']: + expansion = expand_pattern(expansion_pattern, + test_expansion_schema) + for selection in permute_expansion(expansion, artifact_order): + selection_path = selection_pattern % selection + if not selection_path in exclusion_dict: + generate_selection(selection, + spec, + html_template) + else: + print 'Excluding selection:', selection_path + + +def main(target, spec_filename): + spec_json = load_spec_json(spec_filename); + spec_validator.assert_valid_spec_json(spec_json) + generate_test_source_files(spec_json, target) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Test suite generator utility') + parser.add_argument('-t', '--target', type = str, + choices = ("release", "debug"), default = "release", + help = 'Sets the appropriate template for generating tests') + parser.add_argument('-s', '--spec', type = str, default = None, + help = 'Specify a file used for describing and generating the tests') + # TODO(kristijanburnik): Add option for the spec_json file. + args = parser.parse_args() + main(args.target, args.spec)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/regenerate b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/regenerate new file mode 100755 index 0000000..e6bd635 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/regenerate
@@ -0,0 +1,3 @@ +#!/bin/bash +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +python $DIR/clean.py && python $DIR/generate.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/spec_validator.py b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/spec_validator.py new file mode 100755 index 0000000..a6acc104 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mixed-content/generic/tools/spec_validator.py
@@ -0,0 +1,159 @@ +#!/usr/bin/env python + +import json, sys +from common_paths import * + +def assert_non_empty_string(obj, field): + assert field in obj, 'Missing field "%s"' % field + assert isinstance(obj[field], basestring), \ + 'Field "%s" must be a string' % field + assert len(obj[field]) > 0, 'Field "%s" must not be empty' % field + + +def assert_non_empty_list(obj, field): + assert isinstance(obj[field], list), \ + '%s must be a list' % field + assert len(obj[field]) > 0, \ + '%s list must not be empty' % field + + +def assert_non_empty_dict(obj, field): + assert isinstance(obj[field], dict), \ + '%s must be a dict' % field + assert len(obj[field]) > 0, \ + '%s dict must not be empty' % field + + +def assert_contains(obj, field): + assert field in obj, 'Must contain field "%s"' % field + + +def assert_string_from(obj, field, items): + assert obj[field] in items, \ + 'Field "%s" must be from: %s' % (field, str(items)) + + +def assert_string_or_list_items_from(obj, field, items): + if isinstance(obj[field], basestring): + assert_string_from(obj, field, items) + return + + assert isinstance(obj[field], list), "%s must be a list!" % field + for allowed_value in obj[field]: + assert allowed_value != '*', "Wildcard is not supported for lists!" + assert allowed_value in items, \ + 'Field "%s" must be from: %s' % (field, str(items)) + + +def assert_contains_only_fields(obj, expected_fields): + for expected_field in expected_fields: + assert_contains(obj, expected_field) + + for actual_field in obj: + assert actual_field in expected_fields, \ + 'Unexpected field "%s".' % actual_field + + +def assert_value_unique_in(value, used_values): + assert value not in used_values, 'Duplicate value "%s"!' % str(value) + used_values[value] = True + + +def assert_valid_artifact(exp_pattern, artifact_key, schema): + if isinstance(schema, list): + assert_string_or_list_items_from(exp_pattern, artifact_key, + ["*"] + schema) + return + + for sub_artifact_key, sub_schema in schema.iteritems(): + assert_valid_artifact(exp_pattern[artifact_key], sub_artifact_key, + sub_schema) + +def validate(spec_json, details): + """ Validates the json specification for generating tests. """ + + details['object'] = spec_json + assert_contains_only_fields(spec_json, ["specification", + "test_expansion_schema", + "excluded_tests"]) + assert_non_empty_list(spec_json, "specification") + assert_non_empty_dict(spec_json, "test_expansion_schema") + assert_non_empty_list(spec_json, "excluded_tests") + + specification = spec_json['specification'] + test_expansion_schema = spec_json['test_expansion_schema'] + excluded_tests = spec_json['excluded_tests'] + + valid_test_expansion_fields = ['name'] + test_expansion_schema.keys() + + # Validate each single spec. + for spec in specification: + details['object'] = spec + + # Validate required fields for a single spec. + assert_contains_only_fields(spec, ['name', + 'title', + 'description', + 'specification_url', + 'test_expansion']) + assert_non_empty_string(spec, 'name') + assert_non_empty_string(spec, 'title') + assert_non_empty_string(spec, 'description') + assert_non_empty_string(spec, 'specification_url') + assert_non_empty_list(spec, 'test_expansion') + + # Validate spec's test expansion. + used_spec_names = {} + + for spec_exp in spec['test_expansion']: + details['object'] = spec_exp + assert_non_empty_string(spec_exp, 'name') + # The name is unique in same expansion group. + assert_value_unique_in((spec_exp['expansion'], spec_exp['name']), + used_spec_names) + assert_contains_only_fields(spec_exp, valid_test_expansion_fields) + + for artifact in test_expansion_schema: + details['test_expansion_field'] = artifact + assert_valid_artifact(spec_exp, artifact, + test_expansion_schema[artifact]) + del details['test_expansion_field'] + + # Validate the test_expansion schema members. + details['object'] = test_expansion_schema + assert_contains_only_fields(test_expansion_schema, ['expansion', + 'source_scheme', + 'opt_in_method', + 'context_nesting', + 'redirection', + 'subresource', + 'origin', + 'expectation']) + # Validate excluded tests. + details['object'] = excluded_tests + for excluded_test_expansion in excluded_tests: + assert_contains_only_fields(excluded_test_expansion, + valid_test_expansion_fields) + + + del details['object'] + + +def assert_valid_spec_json(spec_json): + error_details = {} + try: + validate(spec_json, error_details) + except AssertionError, err: + print 'ERROR:', err.message + print json.dumps(error_details, indent=4) + sys.exit(1) + + +def main(): + spec_json = load_spec_json(); + assert_valid_spec_json(spec_json) + print "Spec JSON is valid." + + +if __name__ == '__main__': + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/build.sh b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/build.sh new file mode 100755 index 0000000..f69fa4f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/build.sh
@@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -ex + +cd "${0%/*}" +virtualenv -p python .virtualenv +.virtualenv/bin/pip install pyyaml cairocffi +.virtualenv/bin/python gentest.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/gentest.py b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/gentest.py new file mode 100644 index 0000000..1037482 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/gentest.py
@@ -0,0 +1,6 @@ +import sys +sys.path.insert(0, '../../2dcontext/tools/') +import gentestutils +from gentestutils import genTestUtils + +genTestUtils('../../offscreen-canvas', '../../offscreen-canvas', 'templates.yaml', 'name2dir.yaml', True)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/name2dir.yaml b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/name2dir.yaml new file mode 100644 index 0000000..9c6e054 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/name2dir.yaml
@@ -0,0 +1,23 @@ +2d.state: "the-canvas-state" +2d.transformation: "transformations" +2d.composite: "compositing" +2d.fillStyle: "fill-and-stroke-styles" +2d.gradient: "fill-and-stroke-styles" +2d.pattern: "fill-and-stroke-styles" +2d.strokeStyle: "fill-and-stroke-styles" +2d.shadow: "shadows" +2d.clearRect: "drawing-rectangles-to-the-canvas" +2d.fillRect: "drawing-rectangles-to-the-canvas" +2d.strokeRect: "drawing-rectangles-to-the-canvas" +2d.drawImage: "drawing-images-to-the-canvas" +2d.imageData: "pixel-manipulation" +2d.line: "line-styles" +2d.path: "path-objects" +2d.coordinatespace: "conformance-requirements" +2d.missingargs: "conformance-requirements" +2d.voidreturn: "conformance-requirements" +2d.canvas: "the-offscreen-canvas" +2d.getcontext: "the-offscreen-canvas" +context: "the-offscreen-canvas" +initial: "the-offscreen-canvas" +size: "the-offscreen-canvas"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/templates.yaml b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/templates.yaml new file mode 100644 index 0000000..35740965 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/templates.yaml
@@ -0,0 +1,47 @@ +w3c: | + <!DOCTYPE html> + <!-- DO NOT EDIT! This test has been generated by tools/gentest.py. --> + <title>OffscreenCanvas test: %(name)s</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/common/canvas-tests.js"></script> + + <h1>%(name)s</h1> + <p class="desc">%(desc)s</p> + + %(notes)s + <script> + var t = async_test("%(escaped_desc)s"); + t.step(function() { + + var offscreenCanvas = new OffscreenCanvas(100, 50); + var ctx = offscreenCanvas.getContext('2d'); + + %(code)s + t.done(); + + }); + </script> + + +w3cworker: | + // DO NOT EDIT! This test has been generated by tools/gentest.py. + // OffscreenCanvas test in a worker:%(name)s + // Description:%(desc)s + // Note:%(notes)s + + importScripts("/resources/testharness.js"); + importScripts("/common/canvas-tests.js"); + + var t = async_test("%(escaped_desc)s"); + t.step(function() { + + var offscreenCanvas = new OffscreenCanvas(100, 50); + var ctx = offscreenCanvas.getContext('2d'); + + %(code)s + t.done(); + + }); + done(); +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/tests2d.yaml b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/tests2d.yaml new file mode 100644 index 0000000..fc3b158 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/offscreen-canvas/tools/tests2d.yaml
@@ -0,0 +1,9219 @@ +- meta: | + state = [ # some non-default values to test with + ('strokeStyle', '"#ff0000"'), + ('fillStyle', '"#ff0000"'), + ('globalAlpha', 0.5), + ('lineWidth', 0.5), + ('lineCap', '"round"'), + ('lineJoin', '"round"'), + ('miterLimit', 0.5), + ('shadowOffsetX', 5), + ('shadowOffsetY', 5), + ('shadowBlur', 5), + ('shadowColor', '"#ff0000"'), + ('globalCompositeOperation', '"copy"'), + ] + for key,value in state: + tests.append( { + 'name': '2d.state.saverestore.%s' % key, + 'desc': 'save()/restore() works for %s' % key, + 'testing': [ '2d.state.%s' % key ], + 'code': + """// Test that restore() undoes any modifications + var old = ctx.%(key)s; + ctx.save(); + ctx.%(key)s = %(value)s; + ctx.restore(); + @assert ctx.%(key)s === old; + + // Also test that save() doesn't modify the values + ctx.%(key)s = %(value)s; + old = ctx.%(key)s; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against %(value)s + ctx.save(); + @assert ctx.%(key)s === old; + ctx.restore(); + """ % { 'key':key, 'value':value } + } ) + + tests.append( { + 'name': 'initial.reset.2dstate', + 'desc': 'Resetting the canvas state resets 2D state variables', + 'testing': [ 'initial.reset' ], + 'code': + """offscreenCanvas.width = 100; + var default_val; + """ + "".join( + """ + default_val = ctx.%(key)s; + ctx.%(key)s = %(value)s; + offscreenCanvas.width = 100; + @assert ctx.%(key)s === default_val; + """ % { 'key':key, 'value':value } + for key,value in state), + } ) + +- name: 2d.state.saverestore.transformation + desc: save()/restore() affects the current transformation matrix + testing: + - 2d.state.transformation + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.translate(200, 0); + ctx.restore(); + ctx.fillStyle = '#f00'; + ctx.fillRect(-200, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.state.saverestore.clip + desc: save()/restore() affects the clipping path + testing: + - 2d.state.clip + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 1, 1); + ctx.clip(); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.state.saverestore.path + desc: save()/restore() does not affect the current path + testing: + - 2d.state.path + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 100, 50); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.state.saverestore.bitmap + desc: save()/restore() does not affect the current bitmap + testing: + - 2d.state.bitmap + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.state.saverestore.stack + desc: save()/restore() can be nested as a stack + testing: + - 2d.state.save + - 2d.state.restore + code: | + ctx.lineWidth = 1; + ctx.save(); + ctx.lineWidth = 2; + ctx.save(); + ctx.lineWidth = 3; + @assert ctx.lineWidth === 3; + ctx.restore(); + @assert ctx.lineWidth === 2; + ctx.restore(); + @assert ctx.lineWidth === 1; + +- name: 2d.state.saverestore.stackdepth + desc: save()/restore() stack depth is not unreasonably limited + testing: + - 2d.state.save + - 2d.state.restore + code: | + var limit = 512; + for (var i = 1; i < limit; ++i) + { + ctx.save(); + ctx.lineWidth = i; + } + for (var i = limit-1; i > 0; --i) + { + @assert ctx.lineWidth === i; + ctx.restore(); + } + +- name: 2d.state.saverestore.underflow + desc: restore() with an empty stack has no effect + testing: + - 2d.state.restore.underflow + code: | + for (var i = 0; i < 16; ++i) + ctx.restore(); + ctx.lineWidth = 0.5; + ctx.restore(); + @assert ctx.lineWidth === 0.5; + +- name: 2d.transformation.order + desc: Transformations are applied in the right order + testing: + - 2d.transformation.order + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(2, 1); + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -50, 50, 50); + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.transformation.scale.basic + desc: scale() works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(2, 4); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 12.5); + @assert pixel 90,40 == 0,255,0,255; + +- name: 2d.transformation.scale.zero + desc: scale() with a scale factor of zero works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.translate(50, 0); + ctx.scale(0, 1); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + ctx.save(); + ctx.translate(0, 25); + ctx.scale(1, 0); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.scale.negative + desc: scale() with negative scale factors works + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.scale(-1, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-50, 0, 50, 50); + ctx.restore(); + ctx.save(); + ctx.scale(1, -1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, -50, 50, 50); + ctx.restore(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.transformation.scale.large + desc: scale() with large scale factors works + notes: Not really that large at all, but it hits the limits in Firefox. + testing: + - 2d.transformation.scale + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1e5, 1e5); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 1, 1); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.scale.nonfinite + desc: scale() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 10); + @nonfinite ctx.scale(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.scale.multiple + desc: Multiple scale()s combine + testing: + - 2d.transformation.scale.multiple + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 90,40 == 0,255,0,255; + + +- name: 2d.transformation.rotate.zero + desc: rotate() by 0 does nothing + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rotate(0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.rotate.radians + desc: rotate() uses radians + testing: + - 2d.transformation.rotate.radians + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.rotate.direction + desc: rotate() is clockwise + testing: + - 2d.transformation.rotate.direction + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -100, 50, 100); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.rotate.wrap + desc: rotate() wraps large positive values correctly + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi) + // We need about pi +/- 0.001 in order to get correct-looking results + // 32-bit floats can store pi*4097 with precision 2^-10, so that should + // be safe enough on reasonable implementations + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,2 == 0,255,0,255; + @assert pixel 98,47 == 0,255,0,255; + +- name: 2d.transformation.rotate.wrapnegative + desc: rotate() wraps large negative values correctly + testing: + - 2d.transformation.rotate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rotate(-Math.PI * (1 + 4096)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,2 == 0,255,0,255; + @assert pixel 98,47 == 0,255,0,255; + +- name: 2d.transformation.rotate.nonfinite + desc: rotate() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 10); + @nonfinite ctx.rotate(<0.1 Infinity -Infinity NaN>); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.translate.basic + desc: translate() works + testing: + - 2d.transformation.translate + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + @assert pixel 90,40 == 0,255,0,255; + +- name: 2d.transformation.translate.nonfinite + desc: translate() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 10); + @nonfinite ctx.translate(<0.1 Infinity -Infinity NaN>, <0.1 Infinity -Infinity NaN>); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + + +- name: 2d.transformation.transform.identity + desc: transform() with the identity matrix does nothing + testing: + - 2d.transformation.transform + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.transform(1,0, 0,1, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.transform.skewed + desc: transform() with skewy matrix transforms correctly + testing: + - 2d.transformation.transform + code: | + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.transform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + @assert pixel 21,11 == 0,255,0,255; + @assert pixel 79,11 == 0,255,0,255; + @assert pixel 21,39 == 0,255,0,255; + @assert pixel 79,39 == 0,255,0,255; + @assert pixel 39,19 == 0,255,0,255; + @assert pixel 61,19 == 0,255,0,255; + @assert pixel 39,31 == 0,255,0,255; + @assert pixel 61,31 == 0,255,0,255; + +- name: 2d.transformation.transform.multiply + desc: transform() multiplies the CTM + testing: + - 2d.transformation.transform.multiply + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.transform(1,2, 3,4, 5,6); + ctx.transform(-2,1, 3/2,-1/2, 1,-2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.transformation.transform.nonfinite + desc: transform() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 10); + @nonfinite ctx.transform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + + +- name: 2d.transformation.setTransform.skewed + testing: + - 2d.transformation.setTransform + code: | + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.setTransform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + @assert pixel 21,11 == 0,255,0,255; + @assert pixel 79,11 == 0,255,0,255; + @assert pixel 21,39 == 0,255,0,255; + @assert pixel 79,39 == 0,255,0,255; + @assert pixel 39,19 == 0,255,0,255; + @assert pixel 61,19 == 0,255,0,255; + @assert pixel 39,31 == 0,255,0,255; + @assert pixel 61,31 == 0,255,0,255; + +- name: 2d.transformation.setTransform.multiple + testing: + - 2d.transformation.setTransform.identity + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.setTransform(1/2,0, 0,1/2, 0,0); + ctx.setTransform(2,0, 0,2, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 75,35 == 0,255,0,255; + +- name: 2d.transformation.setTransform.nonfinite + desc: setTransform() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 10); + @nonfinite ctx.setTransform(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.composite.globalAlpha.range + testing: + - 2d.composite.globalAlpha.range + code: | + ctx.globalAlpha = 0.5; + var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = 1.1; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = -0.1; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = 0; + @assert ctx.globalAlpha === 0; + ctx.globalAlpha = 1; + @assert ctx.globalAlpha === 1; + +- name: 2d.composite.globalAlpha.invalid + testing: + - 2d.composite.globalAlpha.range + code: | + ctx.globalAlpha = 0.5; + var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = Infinity; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = -Infinity; + @assert ctx.globalAlpha === a; + ctx.globalAlpha = NaN; + @assert ctx.globalAlpha === a; + +- name: 2d.composite.globalAlpha.default + testing: + - 2d.composite.globalAlpha.default + code: | + @assert ctx.globalAlpha === 1.0; + +- name: 2d.composite.globalAlpha.fill + testing: + - 2d.composite.globalAlpha.shape + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + +- name: 2d.composite.globalAlpha.image + testing: + - 2d.composite.globalAlpha.image + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 2,253,0,255; + }); + +- name: 2d.composite.globalAlpha.canvas + testing: + - 2d.composite.globalAlpha.image + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 50,25 ==~ 2,253,0,255; + +- name: 2d.composite.globalAlpha.imagepattern + testing: + - 2d.composite.globalAlpha.image + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.fillStyle = ctx.createPattern(response, 'no-repeat'); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + }); + +- name: 2d.composite.globalAlpha.canvaspattern + testing: + - 2d.composite.globalAlpha.image + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 2,253,0,255; + +- name: 2d.composite.globalAlpha.canvascopy + testing: + - 2d.composite.globalAlpha.image + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'copy' + ctx.globalAlpha = 0.51; + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,130; + + +- meta: | + # Composite operation tests + # <http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2007-March/010608.html> + ops = [ + # name FA FB + ('source-over', '1', '1-aA'), + ('destination-over', '1-aB', '1'), + ('source-in', 'aB', '0'), + ('destination-in', '0', 'aA'), + ('source-out', '1-aB', '0'), + ('destination-out', '0', '1-aA'), + ('source-atop', 'aB', '1-aA'), + ('destination-atop', '1-aB', 'aA'), + ('xor', '1-aB', '1-aA'), + ('copy', '1', '0'), + ('lighter', '1', '1'), + ] + + # The ones that change the output when src = (0,0,0,0): + ops_trans = [ 'source-in', 'destination-in', 'source-out', 'destination-atop', 'copy' ]; + + def calc_output((RA, GA, BA, aA), (RB, GB, BB, aB), FA_code, FB_code): + rA, gA, bA = RA*aA, GA*aA, BA*aA + rB, gB, bB = RB*aB, GB*aB, BB*aB + + FA = eval(FA_code) + FB = eval(FB_code) + + rO = rA*FA + rB*FB + gO = gA*FA + gB*FB + bO = bA*FA + bB*FB + aO = aA*FA + aB*FB + + rO = min(255, rO) + gO = min(255, gO) + bO = min(255, bO) + aO = min(1, aO) + + if aO: + RO = rO / aO + GO = gO / aO + BO = bO / aO + else: RO = GO = BO = 0 + + return (RO, GO, BO, aO) + + def to_test((r,g,b,a)): + return '%d,%d,%d,%d' % (round(r), round(g), round(b), round(a*255)) + def to_cairo((r,g,b,a)): + return '%f,%f,%f,%f' % (r/255., g/255., b/255., a) + + for (name, src, dest) in [ + ('solid', (255, 255, 0, 1.0), (0, 255, 255, 1.0)), + ('transparent', (0, 0, 255, 0.75), (0, 255, 0, 0.5)), + # catches the atop, xor and lighter bugs in Opera 9.10 + ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, src, to_test(expected)), + } ) + + for (name, src, dest) in [ ('image', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow75.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/yellow75.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + }); + """ % (dest, op, to_test(expected)), + } ) + + for (name, src, dest) in [ ('canvas', (255, 255, 0, 0.75), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + expected = calc_output(src, dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow75.png' ], + 'code': """ + var offscreenCanvas2 = new OffscreenCanvas(offscreenCanvas.width, offscreenCanvas.height); + var ctx2 = offscreenCanvas2.getContext('2d'); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/yellow75.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx2.drawImage(response, 0, 0); + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + }); + """ % (dest, op, to_test(expected)), + } ) + + for (name, src, dest) in [ ('uncovered.fill', (0, 0, 255, 0.75), (0, 255, 0, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.fillStyle = 'rgba%s'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, src, to_test(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.image', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'drawImage() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/yellow.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 40, 40, 10, 10, 40, 50, 10, 10); + @assert pixel 15,15 ==~ %s +/- 5; + @assert pixel 50,25 ==~ %s +/- 5; + }); + """ % (dest, op, to_test(expected0), to_test(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.nocontext', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'drawImage() of a canvas with no context draws pixels as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 50,25 ==~ %s +/- 5; + """ % (dest, op, to_test(expected0)), + } ) + + for (name, src, dest) in [ ('uncovered.pattern', (255, 255, 0, 1.0), (0, 255, 255, 0.5)) ]: + for op, FA_code, FB_code in ops: + if op not in ops_trans: continue + expected0 = calc_output((0,0,0,0.0), dest, FA_code, FB_code) + tests.append( { + 'name': '2d.composite.%s.%s' % (name, op), + 'desc': 'Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.', + 'testing': [ '2d.composite.%s' % op ], + 'images': [ 'yellow.png' ], + 'code': """ + ctx.fillStyle = 'rgba%s'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/yellow.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.fillStyle = ctx.createPattern(response, 'no-repeat'); + ctx.fillRect(0, 50, 100, 50); + @assert pixel 50,25 ==~ %s +/- 5; + }); + """ % (dest, op, to_test(expected0)), + } ) + + for op, FA_code, FB_code in ops: + tests.append( { + 'name': '2d.composite.clip.%s' % (op), + 'desc': 'fill() does not affect pixels outside the clip region.', + 'testing': [ '2d.composite.%s' % op ], + 'code': """ + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = '%s'; + ctx.rect(-20, -20, 10, 10); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + """ % (op), + } ) + +- name: 2d.composite.operation.get + testing: + - 2d.composite.operation + code: | + var modes = ['source-atop', 'source-in', 'source-out', 'source-over', + 'destination-atop', 'destination-in', 'destination-out', 'destination-over', + 'lighter', 'copy', 'xor']; + for (var i = 0; i < modes.length; ++i) + { + ctx.globalCompositeOperation = modes[i]; + @assert ctx.globalCompositeOperation === modes[i]; + } + +- name: 2d.composite.operation.unrecognised + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'nonexistent'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.darker + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'darker'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.over + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'over'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.clear + testing: + - 2d.composite.operation.clear + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'clear'; + @assert ctx.globalCompositeOperation === 'clear'; + +- name: 2d.composite.operation.highlight + testing: + - 2d.composite.operation.unrecognised + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'highlight'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.nullsuffix + testing: + - 2d.composite.operation.exact + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'source-over\0'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.casesensitive + testing: + - 2d.composite.operation.casesensitive + code: | + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'Source-over'; + @assert ctx.globalCompositeOperation === 'xor'; + +- name: 2d.composite.operation.default + testing: + - 2d.composite.operation.default + code: | + @assert ctx.globalCompositeOperation === 'source-over'; + +- meta: | + # Colour parsing tests + + # Try most of the CSS3 Color <color> values - http://www.w3.org/TR/css3-color/#colorunits + big_float = '1' + ('0' * 39) + big_double = '1' + ('0' * 310) + for name, string, r,g,b,a, notes in [ + ('html4', 'limE', 0,255,0,255, ""), + ('hex3', '#0f0', 0,255,0,255, ""), + ('hex4', '#0f0f', 0,255,0,255, ""), + ('hex6', '#00fF00', 0,255,0,255, ""), + ('hex8', '#00ff00ff', 0,255,0,255, ""), + ('rgb-num', 'rgb(0,255,0)', 0,255,0,255, ""), + ('rgb-clamp-1', 'rgb(-1000, 1000, -1000)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-2', 'rgb(-200%, 200%, -200%)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-3', 'rgb(-2147483649, 4294967298, -18446744073709551619)', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-4', 'rgb(-'+big_float+', '+big_float+', -'+big_float+')', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-clamp-5', 'rgb(-'+big_double+', '+big_double+', -'+big_double+')', 0,255,0,255, 'Assumes colours are clamped to [0,255].'), + ('rgb-percent', 'rgb(0% ,100% ,0%)', 0,255,0,255, 'CSS3 Color says "The integer value 255 corresponds to 100%". (In particular, it is not 254...)'), + ('rgb-eof', 'rgb(0, 255, 0', 0,255,0,255, ""), # see CSS2.1 4.2 "Unexpected end of style sheet" + ('rgba-solid-1', 'rgba( 0 , 255 , 0 , 1 )', 0,255,0,255, ""), + ('rgba-solid-2', 'rgba( 0 , 255 , 0 , 1.0 )', 0,255,0,255, ""), + ('rgba-solid-3', 'rgba( 0 , 255 , 0 , +1 )', 0,255,0,255, ""), + ('rgba-solid-4', 'rgba( -0 , 255 , +0 , 1 )', 0,255,0,255, ""), + ('rgba-num-1', 'rgba( 0 , 255 , 0 , .499 )', 0,255,0,127, ""), + ('rgba-num-2', 'rgba( 0 , 255 , 0 , 0.499 )', 0,255,0,127, ""), + ('rgba-percent', 'rgba(0%,100%,0%,0.499)', 0,255,0,127, ""), # 0.499*255 rounds to 127, both down and nearest, so it should be safe + ('rgba-clamp-1', 'rgba(0, 255, 0, -2)', 0,0,0,0, ""), + ('rgba-clamp-2', 'rgba(0, 255, 0, 2)', 0,255,0,255, ""), + ('rgba-eof', 'rgba(0, 255, 0, 1', 0,255,0,255, ""), + ('transparent-1', 'transparent', 0,0,0,0, ""), + ('transparent-2', 'TrAnSpArEnT', 0,0,0,0, ""), + ('hsl-1', 'hsl(120, 100%, 50%)', 0,255,0,255, ""), + ('hsl-2', 'hsl( -240 , 100% , 50% )', 0,255,0,255, ""), + ('hsl-3', 'hsl(360120, 100%, 50%)', 0,255,0,255, ""), + ('hsl-4', 'hsl(-360240, 100%, 50%)', 0,255,0,255, ""), + ('hsl-5', 'hsl(120.0, 100.0%, 50.0%)', 0,255,0,255, ""), + ('hsl-6', 'hsl(+120, +100%, +50%)', 0,255,0,255, ""), + ('hsl-clamp-1', 'hsl(120, 200%, 50%)', 0,255,0,255, ""), + ('hsl-clamp-2', 'hsl(120, -200%, 49.9%)', 127,127,127,255, ""), + ('hsl-clamp-3', 'hsl(120, 100%, 200%)', 255,255,255,255, ""), + ('hsl-clamp-4', 'hsl(120, 100%, -200%)', 0,0,0,255, ""), + ('hsla-1', 'hsla(120, 100%, 50%, 0.499)', 0,255,0,127, ""), + ('hsla-2', 'hsla( 120.0 , 100.0% , 50.0% , 1 )', 0,255,0,255, ""), + ('hsla-clamp-1', 'hsla(120, 200%, 50%, 1)', 0,255,0,255, ""), + ('hsla-clamp-2', 'hsla(120, -200%, 49.9%, 1)', 127,127,127,255, ""), + ('hsla-clamp-3', 'hsla(120, 100%, 200%, 1)', 255,255,255,255, ""), + ('hsla-clamp-4', 'hsla(120, 100%, -200%, 1)', 0,0,0,255, ""), + ('hsla-clamp-5', 'hsla(120, 100%, 50%, 2)', 0,255,0,255, ""), + ('hsla-clamp-6', 'hsla(120, 100%, 0%, -2)', 0,0,0,0, ""), + ('svg-1', 'gray', 128,128,128,255, ""), + ('svg-2', 'grey', 128,128,128,255, ""), + # css-color-4 rgb() color function + # https://drafts.csswg.org/css-color/#numeric-rgb + ('css-color-4-rgb-1', 'rgb(0, 255.0, 0)', 0,255,0,255, ""), + ('css-color-4-rgb-2', 'rgb(0, 255, 0, 0.2)', 0,255,0,51, ""), + ('css-color-4-rgb-3', 'rgb(0, 255, 0, 20%)', 0,255,0,51, ""), + ('css-color-4-rgb-4', 'rgb(0 255 0)', 0,255,0,255, ""), + ('css-color-4-rgb-5', 'rgb(0 255 0 / 0.2)', 0,255,0,51, ""), + ('css-color-4-rgb-6', 'rgb(0 255 0 / 20%)', 0,255,0,51, ""), + ('css-color-4-rgba-1', 'rgba(0, 255.0, 0)', 0,255,0,255, ""), + ('css-color-4-rgba-2', 'rgba(0, 255, 0, 0.2)', 0,255,0,51, ""), + ('css-color-4-rgba-3', 'rgba(0, 255, 0, 20%)', 0,255,0,51, ""), + ('css-color-4-rgba-4', 'rgba(0 255 0)', 0,255,0,255, ""), + ('css-color-4-rgba-5', 'rgba(0 255 0 / 0.2)', 0,255,0,51, ""), + ('css-color-4-rgba-6', 'rgba(0 255 0 / 20%)', 0,255,0,51, ""), + # css-color-4 hsl() color function + # https://drafts.csswg.org/css-color/#the-hsl-notation + ('css-color-4-hsl-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""), + ('css-color-4-hsl-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsl-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsl-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-1', 'hsl(120 100.0% 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-2', 'hsl(120 100.0% 50.0% / 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-3', 'hsl(120.0, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-4', 'hsl(120.0, 100.0%, 50.0%, 20%)', 0,255,0,51, ""), + ('css-color-4-hsla-5', 'hsl(120deg, 100.0%, 50.0%, 0.2)', 0,255,0,51, ""), + ('css-color-4-hsla-6', 'hsl(120deg, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-7', 'hsl(133.33333333grad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-8', 'hsl(2.0943951024rad, 100.0%, 50.0%)', 0,255,0,255, ""), + ('css-color-4-hsla-9', 'hsl(0.3333333333turn, 100.0%, 50.0%)', 0,255,0,255, ""), + # currentColor is handled later + ]: + # TODO: test by retrieving fillStyle, instead of actually drawing? + # TODO: test strokeStyle, shadowColor in the same way + test = { + 'name': '2d.fillStyle.parse.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'notes': notes, + 'code': """ + ctx.fillStyle = '#f00'; + ctx.fillStyle = '%s'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == %d,%d,%d,%d; + """ % (string, r,g,b,a), + } + tests.append(test) + + # Also test that invalid colours are ignored + for name, string in [ + ('hex1', '#f'), + ('hex2', '#f0'), + ('hex3', '#g00'), + ('hex4', '#fg00'), + ('hex5', '#ff000'), + ('hex6', '#fg0000'), + ('hex7', '#ff0000f'), + ('hex8', '#fg0000ff'), + ('rgb-1', 'rgb(255.0, 0, 0,)'), + ('rgb-2', 'rgb(100%, 0, 0)'), + ('rgb-3', 'rgb(255, - 1, 0)'), + ('rgba-1', 'rgba(100%, 0, 0, 1)'), + ('rgba-2', 'rgba(255, 0, 0, 1. 0)'), + ('rgba-3', 'rgba(255, 0, 0, 1.)'), + ('rgba-4', 'rgba(255, 0, 0, '), + ('rgba-5', 'rgba(255, 0, 0, 1,)'), + ('hsl-1', 'hsl(0%, 100%, 50%)'), + ('hsl-2', 'hsl(z, 100%, 50%)'), + ('hsl-3', 'hsl(0, 0, 50%)'), + ('hsl-4', 'hsl(0, 100%, 0)'), + ('hsl-5', 'hsl(0, 100.%, 50%)'), + ('hsl-6', 'hsl(0, 100%, 50%,)'), + ('hsla-1', 'hsla(0%, 100%, 50%, 1)'), + ('hsla-2', 'hsla(0, 0, 50%, 1)'), + ('hsla-3', 'hsla(0, 0, 50%, 1,)'), + ('name-1', 'darkbrown'), + ('name-2', 'firebrick1'), + ('name-3', 'red blue'), + ('name-4', '"red"'), + ('name-5', '"red'), + # css-color-4 color function + # comma and comma-less expressions should not mix together. + ('css-color-4-rgb-1', 'rgb(255, 0, 0 / 1)'), + ('css-color-4-rgb-2', 'rgb(255 0 0, 1)'), + ('css-color-4-rgb-3', 'rgb(255, 0 0)'), + ('css-color-4-rgba-1', 'rgba(255, 0, 0 / 1)'), + ('css-color-4-rgba-2', 'rgba(255 0 0, 1)'), + ('css-color-4-rgba-3', 'rgba(255, 0 0)'), + ('css-color-4-hsl-1', 'hsl(0, 100%, 50% / 1)'), + ('css-color-4-hsl-2', 'hsl(0 100% 50%, 1)'), + ('css-color-4-hsl-3', 'hsl(0, 100% 50%)'), + ('css-color-4-hsla-1', 'hsla(0, 100%, 50% / 1)'), + ('css-color-4-hsla-2', 'hsla(0 100% 50%, 1)'), + ('css-color-4-hsla-3', 'hsla(0, 100% 50%)'), + # trailing slash + ('css-color-4-rgb-4', 'rgb(0 0 0 /)'), + ('css-color-4-rgb-5', 'rgb(0, 0, 0 /)'), + ('css-color-4-hsl-4', 'hsl(0 100% 50% /)'), + ('css-color-4-hsl-5', 'hsl(0, 100%, 50% /)'), + ]: + test = { + 'name': '2d.fillStyle.parse.invalid.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'code': """ + ctx.fillStyle = '#0f0'; + try { ctx.fillStyle = '%s'; } catch (e) { } // this shouldn't throw, but it shouldn't matter here if it does + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + """ % string, + } + tests.append(test) + + # Some can't have positive tests, only negative tests, because we don't know what colour they're meant to be + for name, string in [ + ('system', 'ThreeDDarkShadow'), + #('flavor', 'flavor'), # removed from latest CSS3 Color drafts + ]: + test = { + 'name': '2d.fillStyle.parse.%s' % name, + 'testing': [ '2d.colours.parse' ], + 'code': """ + ctx.fillStyle = '#f00'; + ctx.fillStyle = '%s'; + @assert ctx.fillStyle =~ /^#(?!(FF0000|ff0000|f00)$)/; // test that it's not red + """ % (string,), + } + tests.append(test) + +- name: 2d.fillStyle.invalidstring + testing: + - 2d.colours.invalidstring + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillStyle = 'invalid'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillStyle.invalidtype + testing: + - 2d.colours.invalidtype + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillStyle = null; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillStyle.get.solid + testing: + - 2d.colours.getcolour + - 2d.serializecolour.solid + code: | + ctx.fillStyle = '#fa0'; + @assert ctx.fillStyle === '#ffaa00'; + +- name: 2d.fillStyle.get.semitransparent + testing: + - 2d.colours.getcolour + - 2d.serializecolour.transparent + code: | + ctx.fillStyle = 'rgba(255,255,255,0.45)'; + @assert ctx.fillStyle =~ /^rgba\(255, 255, 255, 0\.4\d+\)$/; + +- name: 2d.fillStyle.get.transparent + testing: + - 2d.colours.getcolour + - 2d.serializecolour.transparent + code: | + ctx.fillStyle = 'rgba(0,0,0,0)'; + @assert ctx.fillStyle === 'rgba(0, 0, 0, 0)'; + +- name: 2d.fillStyle.default + testing: + - 2d.colours.default + code: | + @assert ctx.fillStyle === '#000000'; + +- name: 2d.strokeStyle.default + testing: + - 2d.colours.default + code: | + @assert ctx.strokeStyle === '#000000'; + +- name: 2d.gradient.interpolate.solid + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.gradient.interpolate.colour + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 191,191,63,255 +/- 3; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 3; + @assert pixel 75,25 ==~ 63,63,191,255 +/- 3; + +- name: 2d.gradient.interpolate.alpha + testing: + - 2d.gradient.interpolate.linear + code: | + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(0,0,255, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 191,191,63,255 +/- 3; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 3; + @assert pixel 75,25 ==~ 63,63,191,255 +/- 3; + +- name: 2d.gradient.interpolate.colouralpha + testing: + - 2d.gradient.interpolate.alpha + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(255,255,0, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 25,25 ==~ 190,190,65,65 +/- 3; + @assert pixel 50,25 ==~ 126,126,128,128 +/- 3; + @assert pixel 75,25 ==~ 62,62,192,192 +/- 3; + +- name: 2d.gradient.interpolate.outside + testing: + - 2d.gradient.outside.first + - 2d.gradient.outside.last + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(25, 0, 75, 0); + g.addColorStop(0.4, '#0f0'); + g.addColorStop(0.6, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 80,25 ==~ 0,255,0,255; + +- name: 2d.gradient.interpolate.zerosize.fill + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.rect(0, 0, 100, 50); + ctx.fill(); + @assert pixel 40,20 == 0,255,0,255; + +- name: 2d.gradient.interpolate.zerosize.stroke + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.strokeStyle = g; + ctx.rect(20, 20, 60, 10); + ctx.stroke(); + @assert pixel 19,19 == 0,255,0,255; + @assert pixel 20,19 == 0,255,0,255; + @assert pixel 21,19 == 0,255,0,255; + @assert pixel 19,20 == 0,255,0,255; + @assert pixel 20,20 == 0,255,0,255; + @assert pixel 21,20 == 0,255,0,255; + @assert pixel 19,21 == 0,255,0,255; + @assert pixel 20,21 == 0,255,0,255; + @assert pixel 21,21 == 0,255,0,255; + +- name: 2d.gradient.interpolate.zerosize.fillRect + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 40,20 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.interpolate.zerosize.strokeRect + testing: + - 2d.gradient.linear.zerosize + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.strokeStyle = g; + ctx.strokeRect(20, 20, 60, 10); + @assert pixel 19,19 == 0,255,0,255; + @assert pixel 20,19 == 0,255,0,255; + @assert pixel 21,19 == 0,255,0,255; + @assert pixel 19,20 == 0,255,0,255; + @assert pixel 20,20 == 0,255,0,255; + @assert pixel 21,20 == 0,255,0,255; + @assert pixel 19,21 == 0,255,0,255; + @assert pixel 20,21 == 0,255,0,255; + @assert pixel 21,21 == 0,255,0,255; + + +- name: 2d.gradient.interpolate.vertical + testing: + - 2d.gradient.interpolate.linear + code: | + var g = ctx.createLinearGradient(0, 0, 0, 50); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,12 ==~ 191,191,63,255 +/- 10; + @assert pixel 50,25 ==~ 127,127,127,255 +/- 5; + @assert pixel 50,37 ==~ 63,63,191,255 +/- 10; + +- name: 2d.gradient.interpolate.multiple + testing: + - 2d.gradient.interpolate.linear + code: | + offscreenCanvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.5, '#0ff'); + g.addColorStop(1, '#f0f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + @assert pixel 50,25 ==~ 127,255,127,255 +/- 3; + @assert pixel 100,25 ==~ 0,255,255,255 +/- 3; + @assert pixel 150,25 ==~ 127,127,255,255 +/- 3; + +- name: 2d.gradient.interpolate.overlap + testing: + - 2d.gradient.interpolate.overlap + code: | + offscreenCanvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.25, '#00f'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#ff0'); + g.addColorStop(0.5, '#00f'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.75, '#00f'); + g.addColorStop(0.75, '#f00'); + g.addColorStop(0.75, '#ff0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + @assert pixel 49,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 51,25 ==~ 255,255,0,255 +/- 16; + @assert pixel 99,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 101,25 ==~ 255,255,0,255 +/- 16; + @assert pixel 149,25 ==~ 0,0,255,255 +/- 16; + @assert pixel 151,25 ==~ 255,255,0,255 +/- 16; + +- name: 2d.gradient.interpolate.overlap2 + testing: + - 2d.gradient.interpolate.overlap + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ]; + for (var p = 0; p < ps.length; ++p) + { + g.addColorStop(ps[p], '#0f0'); + for (var i = 0; i < 15; ++i) + g.addColorStop(ps[p], '#f00'); + g.addColorStop(ps[p], '#0f0'); + } + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 30,25 == 0,255,0,255; + @assert pixel 40,25 == 0,255,0,255; + @assert pixel 60,25 == 0,255,0,255; + @assert pixel 80,25 == 0,255,0,255; + +- name: 2d.gradient.empty + testing: + - 2d.gradient.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 0, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.gradient.object.update + testing: + - 2d.gradient.update + code: | + var g = ctx.createLinearGradient(-100, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + g.addColorStop(0.1, '#0f0'); + g.addColorStop(0.9, '#0f0'); + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.gradient.object.compare + testing: + - 2d.gradient.object + code: | + var g1 = ctx.createLinearGradient(0, 0, 100, 0); + var g2 = ctx.createLinearGradient(0, 0, 100, 0); + @assert g1 !== g2; + ctx.fillStyle = g1; + @assert ctx.fillStyle === g1; + +- name: 2d.gradient.object.crosscanvas + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var g = offscreenCanvas2.getContext('2d').createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.gradient.object.invalidoffset + testing: + - 2d.gradient.invalidoffset + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + @assert throws INDEX_SIZE_ERR g.addColorStop(-1, '#000'); + @assert throws INDEX_SIZE_ERR g.addColorStop(2, '#000'); + @assert throws TypeError g.addColorStop(Infinity, '#000'); + @assert throws TypeError g.addColorStop(-Infinity, '#000'); + @assert throws TypeError g.addColorStop(NaN, '#000'); + +- name: 2d.gradient.object.invalidcolour + testing: + - 2d.gradient.invalidcolour + code: | + var g = ctx.createLinearGradient(0, 0, 100, 0); + @assert throws SYNTAX_ERR g.addColorStop(0, ""); + @assert throws SYNTAX_ERR g.addColorStop(0, 'null'); + @assert throws SYNTAX_ERR g.addColorStop(0, 'undefined'); + @assert throws SYNTAX_ERR g.addColorStop(0, null); + @assert throws SYNTAX_ERR g.addColorStop(0, undefined); + +- name: 2d.gradient.linear.nonfinite + desc: createLinearGradient() throws TypeError if arguments are not finite + testing: + - 2d.gradient.linear.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createLinearGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + +- name: 2d.gradient.linear.transform.1 + desc: Linear gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.linear.transform + code: | + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.gradient.linear.transform.2 + desc: Linear gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.linear.transform + code: | + ctx.translate(100, 0); + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-150, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.gradient.linear.transform.3 + desc: Linear gradient transforms do not experience broken caching effects + testing: + - 2d.gradient.linear.transform + code: | + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.gradient.radial.negative + desc: createRadialGradient() throws INDEX_SIZE_ERR if either radius is negative + testing: + - 2d.gradient.radial.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); + @assert throws INDEX_SIZE_ERR ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); +- name: 2d.gradient.radial.nonfinite + + desc: createRadialGradient() throws TypeError if arguments are not finite + testing: + - 2d.gradient.radial.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createRadialGradient(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>); + +- name: 2d.gradient.radial.inside1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.inside2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.inside3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(0.993, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.outside1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.outside2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.outside3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.001, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.touch1 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.radial.touch2 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150); + g.addColorStop(0, '#f00'); + g.addColorStop(0.01, '#0f0'); + g.addColorStop(0.99, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.touch3 + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.radial.equal + testing: + - 2d.gradient.radial.equal + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.radial.cone.behind + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.radial.cone.front + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.cone.bottom + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.cone.top + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.cone.beside + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; @moz-todo + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; @moz-todo + @assert pixel 98,25 == 0,255,0,255; @moz-todo + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; @moz-todo + +- name: 2d.gradient.radial.cone.cylinder + testing: + - 2d.gradient.radial.rendering + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.cone.shape1 + testing: + - 2d.gradient.radial.rendering + code: | + var tol = 1; // tolerance to avoid antialiasing artifacts + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(30+tol, 40); + ctx.lineTo(110, -20+tol); + ctx.lineTo(110, 100-tol); + ctx.fill(); + var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.cone.shape2 + testing: + - 2d.gradient.radial.rendering + code: | + var tol = 1; // tolerance to avoid antialiasing artifacts + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(30-tol, 40); + ctx.lineTo(110, -20-tol); + ctx.lineTo(110, 100+tol); + ctx.fill(); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,1 == 0,255,0,255; @moz-todo + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.gradient.radial.transform.1 + desc: Radial gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.radial.transform + code: | + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.gradient.radial.transform.2 + desc: Radial gradient coordinates are relative to the coordinate space at the time of filling + testing: + - 2d.gradient.radial.transform + code: | + ctx.translate(100, 0); + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.gradient.radial.transform.3 + desc: Radial gradient transforms do not experience broken caching effects + testing: + - 2d.gradient.radial.transform + code: | + var g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.pattern.basic.image + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.basic.canvas + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + var pattern = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.pattern.basic.zerocanvas + testing: + - 2d.pattern.zerocanvas + code: | + offscreenCanvas.width = 0; + offscreenCanvas.height = 10; + @assert offscreenCanvas.width === 0; + @assert offscreenCanvas.height === 10; + @assert throws INVALID_STATE_ERR ctx.createPattern(offscreenCanvas, 'repeat'); + offscreenCanvas.width = 10; + offscreenCanvas.height = 0; + @assert offscreenCanvas.width === 10; + @assert offscreenCanvas.height === 0; + @assert throws INVALID_STATE_ERR ctx.createPattern(offscreenCanvas, 'repeat'); + offscreenCanvas.width = 0; + offscreenCanvas.height = 0; + @assert offscreenCanvas.width === 0; + @assert offscreenCanvas.height === 0; + @assert throws INVALID_STATE_ERR ctx.createPattern(offscreenCanvas, 'repeat'); + +- name: 2d.pattern.basic.nocontext + testing: + - 2d.pattern.painting + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var pattern = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.pattern.image.undefined + testing: + - 2d.pattern.IDL + code: | + @assert throws TypeError ctx.createPattern(undefined, 'repeat'); + +- name: 2d.pattern.image.null + testing: + - 2d.pattern.IDL + code: | + @assert throws TypeError ctx.createPattern(null, 'repeat'); + +- name: 2d.pattern.image.string + testing: + - 2d.pattern.IDL + code: | + @assert throws TypeError ctx.createPattern('../images/red.png', 'repeat'); + +- name: 2d.pattern.repeat.empty + testing: + - 2d.pattern.missing + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green-1x1.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, ""); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 200, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.repeat.null + testing: + - 2d.pattern.unrecognised + code: | + @assert ctx.createPattern(offscreenCanvas, null) != null; + +- name: 2d.pattern.repeat.undefined + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(offscreenCanvas, undefined); + +- name: 2d.pattern.repeat.unrecognised + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(offscreenCanvas, "invalid"); + +- name: 2d.pattern.repeat.unrecognisednull + testing: + - 2d.pattern.unrecognised + code: | + @assert throws SYNTAX_ERR ctx.createPattern(offscreenCanvas, "null"); + +- name: 2d.pattern.repeat.case + testing: + - 2d.pattern.exact + code: | + @assert throws SYNTAX_ERR ctx.createPattern(offscreenCanvas, "Repeat"); + +- name: 2d.pattern.repeat.nullsuffix + testing: + - 2d.pattern.exact + code: | + @assert throws SYNTAX_ERR ctx.createPattern(offscreenCanvas, "repeat\0"); + +- name: 2d.pattern.modify.canvas1 + testing: + - 2d.pattern.modify + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + var pattern = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.pattern.modify.canvas2 + testing: + - 2d.pattern.modify + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + var pattern = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.pattern.crosscanvas + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var pattern = offscreenCanvas2.getContext('2d').createPattern(response, 'no-repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.norepeat.basic + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.norepeat.outside + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + ctx.fillRect(-100, 0, 100, 50); + ctx.fillRect(0, 50, 100, 50); + ctx.fillRect(100, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.norepeat.coord1 + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 0); + ctx.fillRect(-50, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.norepeat.coord2 + testing: + - 2d.pattern.painting + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.fillStyle = pattern; + ctx.translate(50, 0); + ctx.fillRect(-50, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.norepeat.coord3 + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 25); + ctx.fillRect(-50, -25, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeat.basic + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeat.outside + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(50, 25); + ctx.fillRect(-50, -25, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeat.coord1 + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/rgrg-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.translate(-128, -78); + ctx.fillRect(128, 78, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeat.coord2 + testing: + - 2d.pattern.painting + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/grgr-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeat.coord3 + testing: + - 2d.pattern.painting + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/rgrg-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(-128, -78); + ctx.fillRect(128, 78, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeatx.basic + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 16); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeatx.outside + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 16); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeatx.coord1 + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-x'); + ctx.fillStyle = pattern; + ctx.translate(0, 16); + ctx.fillRect(0, -16, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 16); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeaty.basic + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 16, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeaty.outside + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.repeaty.coord1 + testing: + - 2d.pattern.painting + images: + - red-16x16.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red-16x16.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat-y'); + ctx.fillStyle = pattern; + ctx.translate(48, 0); + ctx.fillRect(-48, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 50); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.orientation.image + desc: Image patterns do not get flipped when painted + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/rrgg-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.save(); + ctx.translate(0, -103); + ctx.fillRect(0, 103, 100, 50); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 25); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + }); + +- name: 2d.pattern.paint.orientation.canvas + desc: Canvas patterns do not get flipped when painted + testing: + - 2d.pattern.painting + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 25); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 25, 100, 25); + var pattern = ctx.createPattern(offscreenCanvas2, 'no-repeat'); + ctx.fillStyle = pattern; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 25); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.shadow.attributes.shadowBlur.initial + testing: + - 2d.shadow.blur.get + - 2d.shadow.blur.initial + code: | + @assert ctx.shadowBlur === 0; + +- name: 2d.shadow.attributes.shadowBlur.valid + testing: + - 2d.shadow.blur.get + - 2d.shadow.blur.set + code: | + ctx.shadowBlur = 1; + @assert ctx.shadowBlur === 1; + ctx.shadowBlur = 0.5; + @assert ctx.shadowBlur === 0.5; + ctx.shadowBlur = 1e6; + @assert ctx.shadowBlur === 1e6; + ctx.shadowBlur = 0; + @assert ctx.shadowBlur === 0; + +- name: 2d.shadow.attributes.shadowBlur.invalid + testing: + - 2d.shadow.blur.invalid + code: | + ctx.shadowBlur = 1; + ctx.shadowBlur = -2; + @assert ctx.shadowBlur === 1; + ctx.shadowBlur = 1; + ctx.shadowBlur = Infinity; + @assert ctx.shadowBlur === 1; + ctx.shadowBlur = 1; + ctx.shadowBlur = -Infinity; + @assert ctx.shadowBlur === 1; + ctx.shadowBlur = 1; + ctx.shadowBlur = NaN; + @assert ctx.shadowBlur === 1; + +- name: 2d.shadow.attributes.shadowOffset.initial + testing: + - 2d.shadow.offset.initial + code: | + @assert ctx.shadowOffsetX === 0; + @assert ctx.shadowOffsetY === 0; + +- name: 2d.shadow.attributes.shadowOffset.valid + testing: + - 2d.shadow.offset.get + - 2d.shadow.offset.set + code: | + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + ctx.shadowOffsetX = 0.5; + ctx.shadowOffsetY = 0.25; + @assert ctx.shadowOffsetX === 0.5; + @assert ctx.shadowOffsetY === 0.25; + ctx.shadowOffsetX = -0.5; + ctx.shadowOffsetY = -0.25; + @assert ctx.shadowOffsetX === -0.5; + @assert ctx.shadowOffsetY === -0.25; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + @assert ctx.shadowOffsetX === 0; + @assert ctx.shadowOffsetY === 0; + ctx.shadowOffsetX = 1e6; + ctx.shadowOffsetY = 1e6; + @assert ctx.shadowOffsetX === 1e6; + @assert ctx.shadowOffsetY === 1e6; + +- name: 2d.shadow.attributes.shadowOffset.invalid + testing: + - 2d.shadow.offset.invalid + code: | + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = Infinity; + ctx.shadowOffsetY = Infinity; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = -Infinity; + ctx.shadowOffsetY = -Infinity; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + ctx.shadowOffsetX = 1; + ctx.shadowOffsetY = 2; + ctx.shadowOffsetX = NaN; + ctx.shadowOffsetY = NaN; + @assert ctx.shadowOffsetX === 1; + @assert ctx.shadowOffsetY === 2; + +- name: 2d.shadow.attributes.shadowColor.initial + testing: + - 2d.shadow.color.initial + code: | + @assert ctx.shadowColor === 'rgba(0, 0, 0, 0)'; + +- name: 2d.shadow.attributes.shadowColor.valid + testing: + - 2d.shadow.color.get + - 2d.shadow.color.set + code: | + ctx.shadowColor = 'lime'; + @assert ctx.shadowColor === '#00ff00'; + ctx.shadowColor = 'RGBA(0,255, 0,0)'; + @assert ctx.shadowColor === 'rgba(0, 255, 0, 0)'; + +- name: 2d.shadow.attributes.shadowColor.invalid + testing: + - 2d.shadow.color.invalid + code: | + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = 'bogus'; + @assert ctx.shadowColor === '#00ff00'; + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = 'red bogus'; + @assert ctx.shadowColor === '#00ff00'; + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = ctx; + @assert ctx.shadowColor === '#00ff00'; + ctx.shadowColor = '#00ff00'; + ctx.shadowColor = undefined; + @assert ctx.shadowColor === '#00ff00'; + +- name: 2d.shadow.enable.off.1 + desc: Shadows are not drawn when only shadowColor is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.shadowColor = '#f00'; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.enable.off.2 + desc: Shadows are not drawn when only shadowColor is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.enable.blur + desc: Shadows are drawn if shadowBlur is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.enable.x + desc: Shadows are drawn if shadowOffsetX is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.enable.y + desc: Shadows are drawn if shadowOffsetY is set + testing: + - 2d.shadow.enable + - 2d.shadow.render + code: | + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 0.1; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.offset.positiveX + desc: Shadows can be offset with positive x + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.offset.negativeX + desc: Shadows can be offset with negative x + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = -50; + ctx.fillRect(50, 0, 50, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.offset.positiveY + desc: Shadows can be offset with positive y + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 25; + ctx.fillRect(0, 0, 100, 25); + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + +- name: 2d.shadow.offset.negativeY + desc: Shadows can be offset with negative y + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = -25; + ctx.fillRect(0, 25, 100, 25); + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + +- name: 2d.shadow.outside + desc: Shadows of shapes outside the visible area can be offset onto the visible area + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 100; + ctx.fillRect(-100, 0, 25, 50); + ctx.shadowOffsetX = -100; + ctx.fillRect(175, 0, 25, 50); + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 100; + ctx.fillRect(25, -100, 50, 25); + ctx.shadowOffsetY = -100; + ctx.fillRect(25, 125, 50, 25); + @assert pixel 12,25 == 0,255,0,255; + @assert pixel 87,25 == 0,255,0,255; + @assert pixel 50,12 == 0,255,0,255; + @assert pixel 50,37 == 0,255,0,255; + +- name: 2d.shadow.clip.1 + desc: Shadows of clipped shapes are still drawn within the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.save(); + ctx.beginPath(); + ctx.rect(50, 0, 50, 50); + ctx.clip(); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + ctx.restore(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.clip.2 + desc: Shadows are not drawn outside the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 50; + ctx.fillRect(0, 0, 50, 50); + ctx.restore(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.clip.3 + desc: Shadows of clipped shapes are still drawn within the clipping region + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.save(); + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 50; + ctx.fillRect(-50, 0, 50, 50); + ctx.restore(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.stroke.basic + desc: Shadows are drawn for strokes + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.moveTo(0, -25); + ctx.lineTo(100, -25); + ctx.stroke(); + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + +- name: 2d.shadow.stroke.cap.1 + desc: Shadows are not drawn for areas outside stroke caps + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.lineCap = 'butt'; + ctx.moveTo(-50, -25); + ctx.lineTo(0, -25); + ctx.moveTo(100, -25); + ctx.lineTo(150, -25); + ctx.stroke(); + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + +- name: 2d.shadow.stroke.cap.2 + desc: Shadows are drawn for stroke caps + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.beginPath(); + ctx.lineWidth = 50; + ctx.lineCap = 'square'; + ctx.moveTo(25, -25); + ctx.lineTo(75, -25); + ctx.stroke(); + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + +- name: 2d.shadow.stroke.join.1 + desc: Shadows are not drawn for areas outside stroke joins + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'bevel'; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.shadow.stroke.join.2 + desc: Shadows are drawn for stroke joins + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.shadow.stroke.join.3 + desc: Shadows are drawn for stroke joins respecting miter limit + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 0.1; + ctx.beginPath(); + ctx.moveTo(-200, -50); + ctx.lineTo(-150, -50); + ctx.lineTo(-151, -100); // (not an exact right angle, to avoid some other bug in Firefox 3) + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.shadow.image.basic + desc: Shadows are drawn for images + testing: + - 2d.shadow.render + images: + - red.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, -50); + @assert pixel 50,25 == 0,255,0,255; + }); + +- name: 2d.shadow.image.transparent.1 + desc: Shadows are not drawn for transparent images + testing: + - 2d.shadow.render + images: + - transparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/transparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, -50); + @assert pixel 50,25 == 0,255,0,255; + }); + +- name: 2d.shadow.image.transparent.2 + desc: Shadows are not drawn for transparent parts of images + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 50, -50); + ctx.shadowColor = '#f00'; + ctx.drawImage(response, -50, -50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + }); + +- name: 2d.shadow.image.alpha + desc: Shadows are drawn correctly for partially-transparent images + testing: + - 2d.shadow.render + images: + - transparent50.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/transparent50.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, -50); + @assert pixel 50,25 ==~ 127,0,127,255; + }); + +- name: 2d.shadow.image.section + desc: Shadows are not drawn for areas outside image source rectangles + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#f00'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 50, 0, 50, 50, 0, -50, 50, 50); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }); + +- name: 2d.shadow.image.scale + desc: Shadows are drawn correctly for scaled images + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0, 100, 50, -10, -50, 240, 50); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }); + +- name: 2d.shadow.canvas.basic + desc: Shadows are drawn for canvases + testing: + - 2d.shadow.render + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.drawImage(offscreenCanvas2, 0, -50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.canvas.transparent.1 + desc: Shadows are not drawn for transparent canvases + testing: + - 2d.shadow.render + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.drawImage(offscreenCanvas2, 0, -50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.canvas.transparent.2 + desc: Shadows are not drawn for transparent parts of canvases + testing: + - 2d.shadow.render + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#f00'; + ctx2.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.drawImage(offscreenCanvas2, 50, -50); + ctx.shadowColor = '#f00'; + ctx.drawImage(offscreenCanvas2, -50, -50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.canvas.alpha + desc: Shadows are drawn correctly for partially-transparent canvases + testing: + - 2d.shadow.render + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = 'rgba(255, 0, 0, 0.5)'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.drawImage(offscreenCanvas2, 0, -50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.pattern.basic + desc: Shadows are drawn for fill patterns + testing: + - 2d.shadow.render + images: + - red.png + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + }); + +- name: 2d.shadow.pattern.transparent.1 + desc: Shadows are not drawn for transparent fill patterns + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + images: + - transparent.png + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/transparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + }); + +- name: 2d.shadow.pattern.transparent.2 + desc: Shadows are not drawn for transparent parts of fill patterns + testing: + - 2d.shadow.render + images: + - redtransparent.png + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + }); + +- name: 2d.shadow.pattern.alpha + desc: Shadows are drawn correctly for partially-transparent fill patterns + testing: + - 2d.shadow.render + images: + - transparent50.png + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/transparent50.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + var pattern = ctx.createPattern(response, 'repeat'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.fillStyle = pattern; + ctx.fillRect(0, -50, 100, 50); + }); + +- name: 2d.shadow.gradient.basic + desc: Shadows are drawn for gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, '#f00'); + gradient.addColorStop(1, '#f00'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.gradient.transparent.1 + desc: Shadows are not drawn for transparent gradient fills + testing: + - 2d.shadow.render + # http://bugs.webkit.org/show_bug.cgi?id=15266 + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, 'rgba(0,0,0,0)'); + gradient.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowOffsetY = 50; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.gradient.transparent.2 + desc: Shadows are not drawn for transparent parts of gradient fills + testing: + - 2d.shadow.render + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, '#f00'); + gradient.addColorStop(0.499, '#f00'); + gradient.addColorStop(0.5, 'rgba(0,0,0,0)'); + gradient.addColorStop(1, 'rgba(0,0,0,0)'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, 0, 50, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + +- name: 2d.shadow.gradient.alpha + desc: Shadows are drawn correctly for partially-transparent gradient fills + testing: + - 2d.shadow.render + code: | + var gradient = ctx.createLinearGradient(0, 0, 100, 0); + gradient.addColorStop(0, 'rgba(255,0,0,0.5)'); + gradient.addColorStop(1, 'rgba(255,0,0,0.5)'); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#00f'; + ctx.fillStyle = gradient; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.transform.1 + desc: Shadows take account of transformations + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.translate(100, 100); + ctx.fillRect(-100, -150, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.transform.2 + desc: Shadow offsets are not affected by transformations + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowOffsetY = 50; + ctx.shadowColor = '#0f0'; + ctx.rotate(Math.PI) + ctx.fillRect(-100, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.shadow.alpha.1 + desc: Shadow colour alpha components are used + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = 'rgba(255, 0, 0, 0.01)'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255 +/- 4; + +- name: 2d.shadow.alpha.2 + desc: Shadow colour alpha components are used + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = 'rgba(0, 0, 255, 0.5)'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.alpha.3 + desc: Shadows are affected by globalAlpha + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 50; + ctx.globalAlpha = 0.5; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.alpha.4 + desc: Shadows with alpha components are correctly affected by globalAlpha + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; // (work around broken Firefox globalAlpha caching) + ctx.shadowColor = 'rgba(0, 0, 255, 0.707)'; + ctx.shadowOffsetY = 50; + ctx.globalAlpha = 0.707; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.alpha.5 + desc: Shadows of shapes with alpha components are drawn correctly + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = 'rgba(64, 0, 0, 0.5)'; + ctx.shadowColor = '#00f'; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 ==~ 127,0,127,255; + +- name: 2d.shadow.composite.1 + desc: Shadows are drawn using globalCompositeOperation + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.shadowColor = '#f00'; + ctx.shadowOffsetX = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, 0, 200, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.shadow.composite.2 + desc: Shadows are drawn using globalCompositeOperation + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 1; + ctx.fillStyle = '#0f0'; + ctx.fillRect(-10, -10, 120, 70); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.shadow.composite.3 + desc: Areas outside shadows are drawn correctly with destination-out + testing: + - 2d.shadow.render + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-out'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 10; + ctx.fillStyle = '#f00'; + ctx.fillRect(200, 0, 100, 50); + @assert pixel 5,5 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.clearRect.basic + desc: clearRect clears to transparent black + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.clearRect.path + desc: clearRect does not affect the current path + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clearRect(0, 0, 16, 16); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.clearRect.zero + desc: clearRect of zero pixels has no effect + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 100, 0); + ctx.clearRect(0, 0, 0, 50); + ctx.clearRect(0, 0, 0, 0); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.clearRect.negative + desc: clearRect of negative sizes works + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.clearRect(0, 0, 50, 25); + ctx.clearRect(100, 0, -50, 25); + ctx.clearRect(0, 50, 50, -25); + ctx.clearRect(100, 50, -50, -25); + @assert pixel 25,12 == 0,0,0,0; + @assert pixel 75,12 == 0,0,0,0; + @assert pixel 25,37 == 0,0,0,0; + @assert pixel 75,37 == 0,0,0,0; + +- name: 2d.clearRect.transform + desc: clearRect is affected by transforms + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.clearRect(0, -5, 10, 5); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.clearRect.globalalpha + desc: clearRect is not affected by globalAlpha + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.1; + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.clearRect.globalcomposite + desc: clearRect is not affected by globalCompositeOperation + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-atop'; + ctx.clearRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.clearRect.clip + desc: clearRect is affected by clipping regions + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + ctx.clearRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.clearRect.shadow + desc: clearRect does not draw shadows + testing: + - 2d.clearRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.clearRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.clearRect.nonfinite + desc: clearRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @nonfinite ctx.clearRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.basic + desc: fillRect works + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.path + desc: fillRect does not affect the current path + testing: + - 2d.fillRect + code: | + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.zero + desc: fillRect of zero pixels has no effect + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 0); + ctx.fillRect(0, 0, 0, 50); + ctx.fillRect(0, 0, 0, 0); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.negative + desc: fillRect of negative sizes works + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + ctx.fillRect(100, 0, -50, 25); + ctx.fillRect(0, 50, 50, -25); + ctx.fillRect(100, 50, -50, -25); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.fillRect.transform + desc: fillRect is affected by transforms + testing: + - 2d.fillRect + code: | + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -5, 10, 5); + @assert pixel 50,25 == 0,255,0,255; + +# don't bother testing globalalpha, globalcomposite because they're already heavily used by other test cases + +- name: 2d.fillRect.clip + desc: fillRect is affected by clipping regions + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.shadow + desc: fillRect draws shadows + testing: + - 2d.fillRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.fillRect(0, -50, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.fillRect.nonfinite + desc: fillRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + @nonfinite ctx.fillRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.basic + desc: strokeRect works + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.path + desc: strokeRect does not affect the current path + testing: + - 2d.strokeRect + code: | + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 5; + ctx.strokeRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.zero.1 + desc: strokeRect of 0x0 pixels draws nothing + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.strokeRect(50, 25, 0, 0); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.strokeRect.zero.2 + desc: strokeRect of 0x0 pixels draws nothing, including caps and joins + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.strokeRect(50, 25, 0, 0); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.strokeRect.zero.3 + desc: strokeRect of Nx0 pixels draws a straight line + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.strokeRect(0, 25, 100, 0); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.zero.4 + desc: strokeRect of Nx0 pixels draws a closed line with no caps + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 250; + ctx.lineCap = 'round'; + ctx.strokeRect(100, 25, 100, 0); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.strokeRect.zero.5 + desc: strokeRect of Nx0 pixels draws a closed line with joins + testing: + - 2d.strokeRect + code: | + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 250; + ctx.lineJoin = 'round'; + ctx.strokeRect(100, 25, 100, 0); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.negative + desc: strokeRect of negative sizes works + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 25; + ctx.strokeRect(12, 12, 26, 1); + ctx.strokeRect(88, 12, -26, 1); + ctx.strokeRect(12, 38, 26, -1); + ctx.strokeRect(88, 38, -26, -1); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.strokeRect.transform + desc: fillRect is affected by transforms + testing: + - 2d.strokeRect + code: | + ctx.scale(10, 10); + ctx.translate(0, 5); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 5; + ctx.strokeRect(2.5, -2.6, 5, 0.2); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.globalalpha + desc: strokeRect is affected by globalAlpha + testing: + - 2d.strokeRect + code: | + ctx.globalAlpha = 0; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.strokeRect.globalcomposite + desc: strokeRect is not affected by globalCompositeOperation + testing: + - 2d.strokeRect + code: | + ctx.globalCompositeOperation = 'source-in'; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(25, 24, 50, 2); + @assert pixel 50,25 == 0,0,0,0; + +- name: 2d.strokeRect.clip + desc: strokeRect is affected by clipping regions + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(0, 0, 16, 16); + ctx.clip(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 16, 16); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.shadow + desc: strokeRect draws shadows + testing: + - 2d.strokeRect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.shadowColor = '#0f0'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 50; + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.strokeRect(0, -75, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.strokeRect.nonfinite + desc: strokeRect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 150; + @nonfinite ctx.strokeRect(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @assert pixel 50,25 == 0,255,0,255; + + +- name: 2d.drawImage.3arg + testing: + - 2d.drawImage.defaultsource + - 2d.drawImage.defaultdest + images: + - red.png + - green.png + code: | + var promise1 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + var promise2 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + Promise.all([promise1, promise2]).then(function(response1, response2) { + ctx.drawImage(response2, 0, 0); + ctx.drawImage(response1, -100, 0); + ctx.drawImage(response1, 100, 0); + ctx.drawImage(response1, 0, -50); + ctx.drawImage(response1, 0, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.5arg + testing: + - 2d.drawImage.defaultsource + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise1 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + var promise2 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + Promise.all([promise1, promise2]).then(function(response1, response2) { + ctx.drawImage(response2, 50, 0, 50, 50); + ctx.drawImage(response1, 0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.9arg.basic + testing: + - 2d.drawImage.paint + images: + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0, 100, 50, 0, 0, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.9arg.sourcepos + testing: + - 2d.drawImage.paint + images: + - rgrg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/rgrg-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 140, 20, 100, 50, 0, 0, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.9arg.sourcesize + testing: + - 2d.drawImage.paint + images: + - rgrg-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/rgrg-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0, 256, 256, 0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 51, 26); + ctx.fillRect(49, 24, 51, 26); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + @assert pixel 20,20 ==~ 0,255,0,255; + @assert pixel 80,20 ==~ 0,255,0,255; + @assert pixel 20,30 ==~ 0,255,0,255; + @assert pixel 80,30 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.9arg.destpos + testing: + - 2d.drawImage.paint + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise1 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + var promise2 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + Promise.all([promise1, promise2]).then(function(response1, response2) { + ctx.drawImage(response2, 0, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage(response1, 0, 0, 100, 50, -100, 0, 100, 50); + ctx.drawImage(response1, 0, 0, 100, 50, 100, 0, 100, 50); + ctx.drawImage(response1, 0, 0, 100, 50, 0, -50, 100, 50); + ctx.drawImage(response1, 0, 0, 100, 50, 0, 50, 100, 50); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.9arg.destsize + testing: + - 2d.drawImage.paint + images: + - red.png + - green.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise1 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + var promise2 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + Promise.all([promise1, promise2]).then(function(response1, response2) { + ctx.drawImage(response2, 1, 1, 1, 1, 0, 0, 100, 50); + ctx.drawImage(response1, 0, 0, 100, 50, -50, 0, 50, 50); + ctx.drawImage(response1, 0, 0, 100, 50, 100, 0, 50, 50); + ctx.drawImage(response1, 0, 0, 100, 50, 0, -25, 100, 25); + ctx.drawImage(response1, 0, 0, 100, 50, 0, 50, 100, 25); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.canvas + testing: + - 2d.drawImage.paint + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + +- name: 2d.drawImage.self.1 + testing: + - 2d.drawImage.self + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.drawImage(offscreenCanvas, 50, 0); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + +- name: 2d.drawImage.self.2 + testing: + - 2d.drawImage.self + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 1, 100, 49); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 1); + ctx.drawImage(offscreenCanvas, 0, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 2); + @assert pixel 0,0 ==~ 0,255,0,255; + @assert pixel 99,0 ==~ 0,255,0,255; + @assert pixel 0,49 ==~ 0,255,0,255; + @assert pixel 99,49 ==~ 0,255,0,255; + +- name: 2d.drawImage.null + testing: + - 2d.drawImage.IDL + code: | + @assert throws TypeError ctx.drawImage(null, 0, 0); + +- name: 2d.drawImage.zerocanvas + testing: + - 2d.drawImage.zerocanvas + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var offscreenCanvas2 = new OffscreenCanvas(0, 10); + ctx.drawImage(offscreenCanvas2, 0, 0); + offscreenCanvas2.width = 10; + offscreenCanvas2.height = 0; + ctx.drawImage(offscreenCanvas2, 0, 0); + offscreenCanvas2.width = 0; + offscreenCanvas2.height = 0; + ctx.drawImage(offscreenCanvas2, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.drawImage.wrongtype + desc: Incorrect image types in drawImage do not match any defined overloads, so WebIDL throws a TypeError + testing: + - 2d.drawImage.IDL + code: | + @assert throws TypeError ctx.drawImage(undefined, 0, 0); + @assert throws TypeError ctx.drawImage(0, 0, 0); + @assert throws TypeError ctx.drawImage("", 0, 0); + +- name: 2d.drawImage.floatsource + testing: + - 2d.drawImage.paint + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 10.1, 10.1, 0.1, 0.1, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.zerosource + desc: drawImage with zero-sized source rectangle throws INDEX_SIZE_ERR + testing: + - 2d.drawImage.zerosource + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 10, 10, 0, 1, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 10, 10, 1, 0, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 10, 10, 0, 0, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.zerosource.image + desc: drawImage with zero-sized source rectangle from image throws INDEX_SIZE_ERR + testing: + - 2d.drawImage.zerosource + images: + - red-zerowidth.svg + - red-zeroheight.svg + - red-zerosize.svg + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red-zerowidth.svg'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response, 0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + }); + +- name: 2d.drawImage.negativesource + desc: Negative source width/height represents the correct rectangle + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/ggrr-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 100, 78, -100, 50, 0, 0, 50, 50); + ctx.drawImage(response, 100, 128, -100, -50, 50, 0, 50, 50); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.negativedest + desc: Negative destination width/height represents the correct rectangle + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/ggrr-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 100, 78, 50, 50, 0, 50, 50, -50); + ctx.drawImage(response, 100, 128, 50, -50, 100, 50, -50, -50); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.negativedir + desc: Negative dimensions do not affect the direction of the image + testing: + - 2d.drawImage.direction + mozilla: { throws } + images: + - ggrr-256x256.png + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/ggrr-256x256.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 178, 50, -100, 0, 0, 50, 100); + ctx.drawImage(response, 0, 78, 50, 100, 50, 100, 50, -100); + @assert pixel 1,1 ==~ 0,255,0,255; + @assert pixel 1,48 ==~ 0,255,0,255; + @assert pixel 98,1 ==~ 0,255,0,255; + @assert pixel 98,48 ==~ 0,255,0,255; + @assert pixel 48,1 ==~ 0,255,0,255; + @assert pixel 48,48 ==~ 0,255,0,255; + @assert pixel 51,1 ==~ 0,255,0,255; + @assert pixel 51,48 ==~ 0,255,0,255; + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.outsidesource + DISABLED: fix this to match the current spec (transparent black outside source) + testing: + - 2d.drawImage.outsidesource + code: | + var promise1 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + var promise2 = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + Promise.all([promise1, promise2]).then(function(response1, response2) { + ctx.drawImage(response2, 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50); + ctx.drawImage(response2, 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50); + ctx.drawImage(response2, 100, 50, -5, -5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, -0.001, 0, 100, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 0, -0.001, 100, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 0, 0, 100.001, 50, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 0, 0, 100, 50.001, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 50, 0, 50.001, 50, 0, 0, 100, 50); @moz-todo + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 0, 0, -5, 5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 0, 0, 5, -5, 0, 0, 100, 50); + @assert throws INDEX_SIZE_ERR ctx.drawImage(response1, 110, 60, -20, -20, 0, 0, 100, 50); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + }); + +- name: 2d.drawImage.broken + testing: + - 2d.drawImage.incomplete.image + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/broken.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + }); + +- name: 2d.drawImage.svg + desc: drawImage() of an SVG image + testing: + - 2d.drawImage.svg + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/green.svg'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.animated.poster + desc: drawImage() of an APNG draws the poster frame + testing: + - 2d.drawImage.animated.image + images: + - anim-poster-gr.png + code: | + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/anim-poster-gr.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; @moz-todo + }); + +- name: 2d.drawImage.path + testing: + - 2d.drawImage.unaffect + code: | + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + ctx.fill(); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.transform + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 0); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.alpha + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.clip + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(-10, -10, 1, 1); + ctx.clip(); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.composite + testing: + - 2d.drawImage.subject + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/red.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.nowrap + desc: Stretched images do not get pixels wrapping around the edges + images: + - redtransparent.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + ctx.drawImage(response, -1950, 0, 2000, 50); + @assert pixel 45,25 ==~ 0,255,0,255; + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 55,25 ==~ 0,255,0,255; + }); + +- name: 2d.drawImage.nonfinite + desc: drawImage() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + images: + - red.png + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var promise = new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", '/images/redtransparent.png'); + xhr.responseType = 'blob'; + xhr.send(); + xhr.onload = function() { + resolve(xhr.response); + }; + }); + promise.then(function(response) { + @nonfinite ctx.drawImage(<response>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + @nonfinite ctx.drawImage(<response>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @nonfinite ctx.drawImage(<response>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <100 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + @assert pixel 50,25 == 0,255,0,255; + }); + +- name: 2d.imageData.create2.basic + desc: createImageData(sw, sh) exists and returns something + testing: + - 2d.imageData.create2.object + code: | + @assert ctx.createImageData(1, 1) !== null; + +- name: 2d.imageData.create1.basic + desc: createImageData(imgdata) exists and returns something + testing: + - 2d.imageData.create1.object + code: | + @assert ctx.createImageData(ctx.createImageData(1, 1)) !== null; + +- name: 2d.imageData.create2.initial + desc: createImageData(sw, sh) returns transparent black data of the right size + testing: + - 2d.imageData.create2.size + - 2d.imageData.create.initial + - 2d.imageData.initial + code: | + var imgdata = ctx.createImageData(10, 20); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + @assert imgdata.width < imgdata.height; + @assert imgdata.width > 0; + var isTransparentBlack = true; + for (var i = 0; i < imgdata.data.length; ++i) + if (imgdata.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create1.initial + desc: createImageData(imgdata) returns transparent black data of the right size + testing: + - 2d.imageData.create1.size + - 2d.imageData.create.initial + - 2d.imageData.initial + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var imgdata1 = ctx.getImageData(0, 0, 10, 20); + var imgdata2 = ctx.createImageData(imgdata1); + @assert imgdata2.data.length === imgdata1.data.length; + @assert imgdata2.width === imgdata1.width; + @assert imgdata2.height === imgdata1.height; + var isTransparentBlack = true; + for (var i = 0; i < imgdata2.data.length; ++i) + if (imgdata2.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create2.large + desc: createImageData(sw, sh) works for sizes much larger than the canvas + testing: + - 2d.imageData.create2.size + code: | + var imgdata = ctx.createImageData(1000, 2000); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + @assert imgdata.width < imgdata.height; + @assert imgdata.width > 0; + var isTransparentBlack = true; + for (var i = 0; i < imgdata.data.length; i += 7813) // check ~1024 points (assuming normal scaling) + if (imgdata.data[i] !== 0) + isTransparentBlack = false; + @assert isTransparentBlack; + +- name: 2d.imageData.create2.negative + desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments + testing: + - 2d.imageData.create2.size + code: | + var imgdata1 = ctx.createImageData(10, 20); + var imgdata2 = ctx.createImageData(-10, 20); + var imgdata3 = ctx.createImageData(10, -20); + var imgdata4 = ctx.createImageData(-10, -20); + @assert imgdata1.data.length === imgdata2.data.length; + @assert imgdata2.data.length === imgdata3.data.length; + @assert imgdata3.data.length === imgdata4.data.length; + +- name: 2d.imageData.create2.zero + desc: createImageData(sw, sh) throws INDEX_SIZE_ERR if size is zero + testing: + - 2d.imageData.getcreate.zero + code: | + @assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0); + @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 10); + @assert throws INDEX_SIZE_ERR ctx.createImageData(0, 0); + +- name: 2d.imageData.create2.nonfinite + desc: createImageData() throws TypeError if arguments are not finite + testing: + - 2d.imageData.getcreate.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.createImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + var posinfobj = { valueOf: function() { return Infinity; } }, + neginfobj = { valueOf: function() { return -Infinity; } }, + nanobj = { valueOf: function() { return -Infinity; } }; + @nonfinite @assert throws TypeError ctx.createImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>); + +- name: 2d.imageData.create1.zero + desc: createImageData(null) throws TypeError + testing: + - 2d.imageData.create.null + code: | + @assert throws TypeError ctx.createImageData(null); + +- name: 2d.imageData.create2.round + desc: createImageData(w, h) is rounded the same as getImageData(0, 0, w, h) + testing: + - 2d.imageData.createround + code: | + var imgdata1 = ctx.createImageData(10.01, 10.99); + var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99); + @assert imgdata1.width === imgdata2.width; + @assert imgdata1.height === imgdata2.height; + +- name: 2d.imageData.get.basic + desc: getImageData() exists and returns something + testing: + - 2d.imageData.get.basic + code: | + @assert ctx.getImageData(0, 0, 100, 50) !== null; + +- name: 2d.imageData.get.zero + desc: getImageData() throws INDEX_SIZE_ERR if size is zero + testing: + - 2d.imageData.getcreate.zero + code: | + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 10); + @assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 0); + +- name: 2d.imageData.get.nonfinite + desc: getImageData() throws TypeError if arguments are not finite + testing: + - 2d.imageData.getcreate.nonfinite + code: | + @nonfinite @assert throws TypeError ctx.getImageData(<10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + var posinfobj = { valueOf: function() { return Infinity; } }, + neginfobj = { valueOf: function() { return -Infinity; } }, + nanobj = { valueOf: function() { return -Infinity; } }; + @nonfinite @assert throws TypeError ctx.getImageData(<10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>, <10 posinfobj neginfobj nanobj>); + +- name: 2d.imageData.get.source.outside + desc: getImageData() returns transparent black outside the canvas + testing: + - 2d.imageData.get.basic + - 2d.imageData.get.outside + code: | + ctx.fillStyle = '#08f'; + ctx.fillRect(0, 0, 100, 50); + var imgdata1 = ctx.getImageData(-10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + @assert imgdata1.data[1] === 0; + @assert imgdata1.data[2] === 0; + @assert imgdata1.data[3] === 0; + var imgdata2 = ctx.getImageData(10, -5, 1, 1); + @assert imgdata2.data[0] === 0; + @assert imgdata2.data[1] === 0; + @assert imgdata2.data[2] === 0; + @assert imgdata2.data[3] === 0; + var imgdata3 = ctx.getImageData(200, 5, 1, 1); + @assert imgdata3.data[0] === 0; + @assert imgdata3.data[1] === 0; + @assert imgdata3.data[2] === 0; + @assert imgdata3.data[3] === 0; + var imgdata4 = ctx.getImageData(10, 60, 1, 1); + @assert imgdata4.data[0] === 0; + @assert imgdata4.data[1] === 0; + @assert imgdata4.data[2] === 0; + @assert imgdata4.data[3] === 0; + var imgdata5 = ctx.getImageData(100, 10, 1, 1); + @assert imgdata5.data[0] === 0; + @assert imgdata5.data[1] === 0; + @assert imgdata5.data[2] === 0; + @assert imgdata5.data[3] === 0; + var imgdata6 = ctx.getImageData(0, 10, 1, 1); + @assert imgdata6.data[0] === 0; + @assert imgdata6.data[1] === 136; + @assert imgdata6.data[2] === 255; + @assert imgdata6.data[3] === 255; + var imgdata7 = ctx.getImageData(-10, 10, 20, 20); + @assert imgdata7.data[ 0*4+0] === 0; + @assert imgdata7.data[ 0*4+1] === 0; + @assert imgdata7.data[ 0*4+2] === 0; + @assert imgdata7.data[ 0*4+3] === 0; + @assert imgdata7.data[ 9*4+0] === 0; + @assert imgdata7.data[ 9*4+1] === 0; + @assert imgdata7.data[ 9*4+2] === 0; + @assert imgdata7.data[ 9*4+3] === 0; + @assert imgdata7.data[10*4+0] === 0; + @assert imgdata7.data[10*4+1] === 136; + @assert imgdata7.data[10*4+2] === 255; + @assert imgdata7.data[10*4+3] === 255; + @assert imgdata7.data[19*4+0] === 0; + @assert imgdata7.data[19*4+1] === 136; + @assert imgdata7.data[19*4+2] === 255; + @assert imgdata7.data[19*4+3] === 255; + @assert imgdata7.data[20*4+0] === 0; + @assert imgdata7.data[20*4+1] === 0; + @assert imgdata7.data[20*4+2] === 0; + @assert imgdata7.data[20*4+3] === 0; + +- name: 2d.imageData.get.source.negative + desc: getImageData() works with negative width and height, and returns top-to-bottom left-to-right + testing: + - 2d.imageData.get.basic + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#fff'; + ctx.fillRect(20, 10, 60, 10); + var imgdata1 = ctx.getImageData(85, 25, -10, -10); + @assert imgdata1.data[0] === 255; + @assert imgdata1.data[1] === 255; + @assert imgdata1.data[2] === 255; + @assert imgdata1.data[3] === 255; + @assert imgdata1.data[imgdata1.data.length-4+0] === 0; + @assert imgdata1.data[imgdata1.data.length-4+1] === 0; + @assert imgdata1.data[imgdata1.data.length-4+2] === 0; + @assert imgdata1.data[imgdata1.data.length-4+3] === 255; + var imgdata2 = ctx.getImageData(0, 0, -1, -1); + @assert imgdata2.data[0] === 0; + @assert imgdata2.data[1] === 0; + @assert imgdata2.data[2] === 0; + @assert imgdata2.data[3] === 0; + +- name: 2d.imageData.get.source.size + desc: getImageData() returns bigger ImageData for bigger source rectangle + testing: + - 2d.imageData.get.basic + code: | + var imgdata1 = ctx.getImageData(0, 0, 10, 10); + var imgdata2 = ctx.getImageData(0, 0, 20, 20); + @assert imgdata2.width > imgdata1.width; + @assert imgdata2.height > imgdata1.height; + +- name: 2d.imageData.get.tiny + desc: getImageData() works for sizes smaller than one pixel + testing: + - 2d.imageData.one + code: | + var imgdata = ctx.getImageData(0, 0, 0.0001, 0.0001); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + @assert imgdata.width === 1; + @assert imgdata.height === 1; + +- name: 2d.imageData.get.nonpremul + desc: getImageData() returns non-premultiplied colours + testing: + - 2d.imageData.get.premul + code: | + ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(10, 10, 10, 10); + @assert imgdata.data[0] > 200; + @assert imgdata.data[1] > 200; + @assert imgdata.data[2] > 200; + @assert imgdata.data[3] > 100; + @assert imgdata.data[3] < 200; + +- name: 2d.imageData.get.range + desc: getImageData() returns values in the range [0, 255] + testing: + - 2d.pixelarray.range + - 2d.pixelarray.retrieve + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#fff'; + ctx.fillRect(20, 10, 60, 10); + var imgdata1 = ctx.getImageData(10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + var imgdata2 = ctx.getImageData(30, 15, 1, 1); + @assert imgdata2.data[0] === 255; + +- name: 2d.imageData.get.clamp + desc: getImageData() clamps colours to the range [0, 255] + testing: + - 2d.pixelarray.range + code: | + ctx.fillStyle = 'rgb(-100, -200, -300)'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = 'rgb(256, 300, 400)'; + ctx.fillRect(20, 10, 60, 10); + var imgdata1 = ctx.getImageData(10, 5, 1, 1); + @assert imgdata1.data[0] === 0; + @assert imgdata1.data[1] === 0; + @assert imgdata1.data[2] === 0; + var imgdata2 = ctx.getImageData(30, 15, 1, 1); + @assert imgdata2.data[0] === 255; + @assert imgdata2.data[1] === 255; + @assert imgdata2.data[2] === 255; + +- name: 2d.imageData.get.length + desc: getImageData() returns a correctly-sized Uint8ClampedArray + testing: + - 2d.pixelarray.length + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data.length === imgdata.width*imgdata.height*4; + +- name: 2d.imageData.get.order.cols + desc: getImageData() returns leftmost columns first + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 2, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0; + @assert imgdata.data[Math.round(imgdata.width/2*4)] === 255; + @assert imgdata.data[Math.round((imgdata.height/2)*imgdata.width*4)] === 0; + +- name: 2d.imageData.get.order.rows + desc: getImageData() returns topmost rows first + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = '#fff'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 2); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0; + @assert imgdata.data[Math.floor(imgdata.width/2*4)] === 0; + @assert imgdata.data[(imgdata.height/2)*imgdata.width*4] === 255; + +- name: 2d.imageData.get.order.rgb + desc: getImageData() returns R then G then B + testing: + - 2d.pixelarray.order + - 2d.pixelarray.indexes + code: | + ctx.fillStyle = '#48c'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[0] === 0x44; + @assert imgdata.data[1] === 0x88; + @assert imgdata.data[2] === 0xCC; + @assert imgdata.data[3] === 255; + @assert imgdata.data[4] === 0x44; + @assert imgdata.data[5] === 0x88; + @assert imgdata.data[6] === 0xCC; + @assert imgdata.data[7] === 255; + +- name: 2d.imageData.get.order.alpha + desc: getImageData() returns A in the fourth component + testing: + - 2d.pixelarray.order + code: | + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert imgdata.data[3] < 200; + @assert imgdata.data[3] > 100; + +- name: 2d.imageData.get.unaffected + desc: getImageData() is not affected by context state + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50) + ctx.save(); + ctx.translate(50, 0); + ctx.globalAlpha = 0.1; + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.rect(0, 0, 5, 5); + ctx.clip(); + var imgdata = ctx.getImageData(0, 0, 50, 50); + ctx.restore(); + ctx.putImageData(imgdata, 50, 0); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + + +- name: 2d.imageData.object.properties + desc: ImageData objects have the right properties + testing: + - 2d.imageData.type + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @assert typeof(imgdata.width) === 'number'; + @assert typeof(imgdata.height) === 'number'; + @assert typeof(imgdata.data) === 'object'; + +- name: 2d.imageData.object.readonly + desc: ImageData objects properties are read-only + testing: + - 2d.imageData.type + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + var w = imgdata.width; + var h = imgdata.height; + var d = imgdata.data; + imgdata.width = 123; + imgdata.height = 123; + imgdata.data = [100,100,100,100]; + @assert imgdata.width === w; + @assert imgdata.height === h; + @assert imgdata.data === d; + @assert imgdata.data[0] === 0; + @assert imgdata.data[1] === 0; + @assert imgdata.data[2] === 0; + @assert imgdata.data[3] === 0; + +- name: 2d.imageData.object.set + desc: ImageData.data can be modified + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + @assert imgdata.data[0] === 100; + imgdata.data[0] = 200; + @assert imgdata.data[0] === 200; + +- name: 2d.imageData.object.undefined + desc: ImageData.data converts undefined to 0 + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = undefined; + @assert imgdata.data[0] === 0; + +- name: 2d.imageData.object.nan + desc: ImageData.data converts NaN to 0 + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = NaN; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = "cheese"; + @assert imgdata.data[0] === 0; + +- name: 2d.imageData.object.string + desc: ImageData.data converts strings to numbers with ToNumber + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = "110"; + @assert imgdata.data[0] === 110; + imgdata.data[0] = 100; + imgdata.data[0] = "0x78"; + @assert imgdata.data[0] === 120; + imgdata.data[0] = 100; + imgdata.data[0] = " +130e0 "; + @assert imgdata.data[0] === 130; + +- name: 2d.imageData.object.clamp + desc: ImageData.data clamps numbers to [0, 255] + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 100; + imgdata.data[0] = 300; + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -100; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = 200+Math.pow(2, 32); + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -200-Math.pow(2, 32); + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = Math.pow(10, 39); + @assert imgdata.data[0] === 255; + imgdata.data[0] = 100; + imgdata.data[0] = -Math.pow(10, 39); + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = -Infinity; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 100; + imgdata.data[0] = Infinity; + @assert imgdata.data[0] === 255; + +- name: 2d.imageData.object.round + desc: ImageData.data rounds numbers with round-to-zero + testing: + - 2d.pixelarray.modify + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + imgdata.data[0] = 0.499; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 0.5; + @assert imgdata.data[0] === 0; + imgdata.data[0] = 0.501; + @assert imgdata.data[0] === 1; + imgdata.data[0] = 1.499; + @assert imgdata.data[0] === 1; + imgdata.data[0] = 1.5; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 1.501; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 2.5; + @assert imgdata.data[0] === 2; + imgdata.data[0] = 3.5; + @assert imgdata.data[0] === 4; + imgdata.data[0] = 252.5; + @assert imgdata.data[0] === 252; + imgdata.data[0] = 253.5; + @assert imgdata.data[0] === 254; + imgdata.data[0] = 254.5; + @assert imgdata.data[0] === 254; + imgdata.data[0] = 256.5; + @assert imgdata.data[0] === 255; + imgdata.data[0] = -0.5; + @assert imgdata.data[0] === 0; + imgdata.data[0] = -1.5; + @assert imgdata.data[0] === 0; + +- name: 2d.imageData.put.null + desc: putImageData() with null imagedata throws TypeError + testing: + - 2d.imageData.put.wrongtype + code: | + @assert throws TypeError ctx.putImageData(null, 0, 0); + +- name: 2d.imageData.put.nonfinite + desc: putImageData() throws TypeError if arguments are not finite + testing: + - 2d.imageData.put.nonfinite + code: | + var imgdata = ctx.getImageData(0, 0, 10, 10); + @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + @nonfinite @assert throws TypeError ctx.putImageData(<imgdata>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>, <10 Infinity -Infinity NaN>); + +- name: 2d.imageData.put.basic + desc: putImageData() puts image data from getImageData() onto the canvas + testing: + - 2d.imageData.put.normal + - 2d.imageData.put.3arg + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.created + desc: putImageData() puts image data from createImageData() onto the canvas + testing: + - 2d.imageData.put.normal + code: | + var imgdata = ctx.createImageData(100, 50); + for (var i = 0; i < imgdata.data.length; i += 4) { + imgdata.data[i] = 0; + imgdata.data[i+1] = 255; + imgdata.data[i+2] = 0; + imgdata.data[i+3] = 255; + } + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.wrongtype + desc: putImageData() does not accept non-ImageData objects + testing: + - 2d.imageData.put.wrongtype + code: | + var imgdata = { width: 1, height: 1, data: [255, 0, 0, 255] }; + @assert throws TypeError ctx.putImageData(imgdata, 0, 0); + @assert throws TypeError ctx.putImageData("cheese", 0, 0); + @assert throws TypeError ctx.putImageData(42, 0, 0); + +- name: 2d.imageData.put.cross + desc: putImageData() accepts image data got from a different canvas + testing: + - 2d.imageData.put.normal + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var ctx2 = offscreenCanvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50) + var imgdata = ctx2.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.alpha + desc: putImageData() puts non-solid image data correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = 'rgba(0, 255, 0, 0.25)'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,64; + +- name: 2d.imageData.put.modified + desc: putImageData() puts modified image data correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(45, 20, 10, 10) + var imgdata = ctx.getImageData(45, 20, 10, 10); + for (var i = 0, len = imgdata.width*imgdata.height*4; i < len; i += 4) + { + imgdata.data[i] = 0; + imgdata.data[i+1] = 255; + } + ctx.putImageData(imgdata, 45, 20); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.dirty.zero + desc: putImageData() with zero-sized dirty rectangle puts nothing + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.dirty.rect1 + desc: putImageData() only modifies areas inside the dirty rectangle, using width and height + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 20, 20) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20); + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + +- name: 2d.imageData.put.dirty.rect2 + desc: putImageData() only modifies areas inside the dirty rectangle, using x and y + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(60, 30, 20, 20) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20); + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + +- name: 2d.imageData.put.dirty.negative + desc: putImageData() handles negative-sized dirty rectangles correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 20, 20) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.fillStyle = '#f00'; + ctx.fillRect(40, 20, 20, 20) + ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20); + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 35,25 ==~ 0,255,0,255; + @assert pixel 65,25 ==~ 0,255,0,255; + @assert pixel 50,15 ==~ 0,255,0,255; + @assert pixel 50,45 ==~ 0,255,0,255; + +- name: 2d.imageData.put.dirty.outside + desc: putImageData() handles dirty rectangles outside the canvas correctly + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20); + ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50); + ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20); + ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20); + @assert pixel 50,25 ==~ 0,255,0,255; + @assert pixel 98,15 ==~ 0,255,0,255; + @assert pixel 98,25 ==~ 0,255,0,255; + @assert pixel 98,45 ==~ 0,255,0,255; + @assert pixel 1,5 ==~ 0,255,0,255; + @assert pixel 1,25 ==~ 0,255,0,255; + @assert pixel 1,45 ==~ 0,255,0,255; + +- name: 2d.imageData.put.unchanged + desc: putImageData(getImageData(...), ...) has no effect + testing: + - 2d.imageData.unchanged + code: | + var i = 0; + for (var y = 0; y < 16; ++y) { + for (var x = 0; x < 16; ++x, ++i) { + ctx.fillStyle = 'rgba(' + i + ',' + (Math.floor(i*1.5) % 256) + ',' + (Math.floor(i*23.3) % 256) + ',' + (i/256) + ')'; + ctx.fillRect(x, y, 1, 1); + } + } + var imgdata1 = ctx.getImageData(0.1, 0.2, 15.8, 15.9); + var olddata = []; + for (var i = 0; i < imgdata1.data.length; ++i) + olddata[i] = imgdata1.data[i]; + ctx.putImageData(imgdata1, 0.1, 0.2); + var imgdata2 = ctx.getImageData(0.1, 0.2, 15.8, 15.9); + for (var i = 0; i < imgdata2.data.length; ++i) { + @assert olddata[i] === imgdata2.data[i]; + } + +- name: 2d.imageData.put.unaffected + desc: putImageData() is not affected by context state + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.globalAlpha = 0.1; + ctx.globalCompositeOperation = 'destination-atop'; + ctx.shadowColor = '#f00'; + ctx.shadowBlur = 1; + ctx.translate(100, 50); + ctx.scale(0.1, 0.1); + ctx.putImageData(imgdata, 0, 0); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.clip + desc: putImageData() is not affected by clipping regions + testing: + - 2d.imageData.unaffected + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50) + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.putImageData(imgdata, 0, 0); + @assert pixel 25,25 ==~ 0,255,0,255; + @assert pixel 75,25 ==~ 0,255,0,255; + +- name: 2d.imageData.put.path + desc: putImageData() does not affect the current path + testing: + - 2d.imageData.put.normal + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50) + ctx.rect(0, 0, 100, 50); + var imgdata = ctx.getImageData(0, 0, 100, 50); + ctx.putImageData(imgdata, 0, 0); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 ==~ 0,255,0,255; + +- name: 2d.line.defaults + testing: + - 2d.lineWidth.default + - 2d.lineCap.default + - 2d.lineJoin.default + - 2d.miterLimit.default + code: | + @assert ctx.lineWidth === 1; + @assert ctx.lineCap === 'butt'; + @assert ctx.lineJoin === 'miter'; + @assert ctx.miterLimit === 10; + +- name: 2d.line.width.basic + desc: lineWidth determines the width of line strokes + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 20; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + @assert pixel 14,25 == 0,255,0,255; + @assert pixel 15,25 == 0,255,0,255; + @assert pixel 16,25 == 0,255,0,255; + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 34,25 == 0,255,0,255; + @assert pixel 35,25 == 0,255,0,255; + @assert pixel 36,25 == 0,255,0,255; + @assert pixel 64,25 == 0,255,0,255; + @assert pixel 65,25 == 0,255,0,255; + @assert pixel 66,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 84,25 == 0,255,0,255; + @assert pixel 85,25 == 0,255,0,255; + @assert pixel 86,25 == 0,255,0,255; + +- name: 2d.line.width.transformed + desc: Line stroke widths are affected by scale transformations + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 4; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.save(); + ctx.scale(5, 1); + ctx.beginPath(); + ctx.moveTo(5, 15); + ctx.lineTo(5, 35); + ctx.stroke(); + ctx.restore(); + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.save(); + ctx.scale(-5, 1); + ctx.beginPath(); + ctx.moveTo(-15, 15); + ctx.lineTo(-15, 35); + ctx.stroke(); + ctx.restore(); + ctx.fillRect(65, 15, 20, 20); + @assert pixel 14,25 == 0,255,0,255; + @assert pixel 15,25 == 0,255,0,255; + @assert pixel 16,25 == 0,255,0,255; + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 34,25 == 0,255,0,255; + @assert pixel 35,25 == 0,255,0,255; + @assert pixel 36,25 == 0,255,0,255; + @assert pixel 64,25 == 0,255,0,255; + @assert pixel 65,25 == 0,255,0,255; + @assert pixel 66,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 84,25 == 0,255,0,255; + @assert pixel 85,25 == 0,255,0,255; + @assert pixel 86,25 == 0,255,0,255; + +- name: 2d.line.width.scaledefault + desc: Default lineWidth strokes are affected by scale transformations + testing: + - 2d.lineWidth + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(50, 50); + ctx.strokeStyle = '#0f0'; + ctx.moveTo(0, 0.5); + ctx.lineTo(2, 0.5); + ctx.stroke(); + @assert pixel 25,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 75,25 == 0,255,0,255; + @assert pixel 50,5 == 0,255,0,255; + @assert pixel 50,45 == 0,255,0,255; + +- name: 2d.line.width.valid + desc: Setting lineWidth to valid values works + testing: + - 2d.lineWidth.set + - 2d.lineWidth.get + code: | + ctx.lineWidth = 1.5; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = "1e1"; + @assert ctx.lineWidth === 10; + ctx.lineWidth = 1/1024; + @assert ctx.lineWidth === 1/1024; + ctx.lineWidth = 1000; + @assert ctx.lineWidth === 1000; + +- name: 2d.line.width.invalid + desc: Setting lineWidth to invalid values is ignored + testing: + - 2d.lineWidth.invalid + code: | + ctx.lineWidth = 1.5; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = 1.5; + ctx.lineWidth = 0; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = 1.5; + ctx.lineWidth = -1; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = 1.5; + ctx.lineWidth = Infinity; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = 1.5; + ctx.lineWidth = -Infinity; + @assert ctx.lineWidth === 1.5; + ctx.lineWidth = 1.5; + ctx.lineWidth = NaN; + @assert ctx.lineWidth === 1.5; + +- name: 2d.line.cap.butt + desc: lineCap 'butt' is rendered correctly + testing: + - 2d.lineCap.butt + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineCap = 'butt'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + @assert pixel 25,14 == 0,255,0,255; + @assert pixel 25,15 == 0,255,0,255; + @assert pixel 25,16 == 0,255,0,255; + @assert pixel 25,34 == 0,255,0,255; + @assert pixel 25,35 == 0,255,0,255; + @assert pixel 25,36 == 0,255,0,255; + @assert pixel 75,14 == 0,255,0,255; + @assert pixel 75,15 == 0,255,0,255; + @assert pixel 75,16 == 0,255,0,255; + @assert pixel 75,34 == 0,255,0,255; + @assert pixel 75,35 == 0,255,0,255; + @assert pixel 75,36 == 0,255,0,255; + +- name: 2d.line.cap.round + desc: lineCap 'round' is rendered correctly + testing: + - 2d.lineCap.round + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var tol = 1; // tolerance to avoid antialiasing artifacts + ctx.lineCap = 'round'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(35-tol, 15); + ctx.arc(25, 15, 10-tol, 0, Math.PI, true); + ctx.arc(25, 35, 10-tol, Math.PI, 0, true); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(85+tol, 15); + ctx.arc(75, 15, 10+tol, 0, Math.PI, true); + ctx.arc(75, 35, 10+tol, Math.PI, 0, true); + ctx.fill(); + @assert pixel 17,6 == 0,255,0,255; + @assert pixel 25,6 == 0,255,0,255; + @assert pixel 32,6 == 0,255,0,255; + @assert pixel 17,43 == 0,255,0,255; + @assert pixel 25,43 == 0,255,0,255; + @assert pixel 32,43 == 0,255,0,255; + @assert pixel 67,6 == 0,255,0,255; + @assert pixel 75,6 == 0,255,0,255; + @assert pixel 82,6 == 0,255,0,255; + @assert pixel 67,43 == 0,255,0,255; + @assert pixel 75,43 == 0,255,0,255; + @assert pixel 82,43 == 0,255,0,255; + +- name: 2d.line.cap.square + desc: lineCap 'square' is rendered correctly + testing: + - 2d.lineCap.square + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineCap = 'square'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 5, 20, 40); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 5, 20, 40); + @assert pixel 25,4 == 0,255,0,255; + @assert pixel 25,5 == 0,255,0,255; + @assert pixel 25,6 == 0,255,0,255; + @assert pixel 25,44 == 0,255,0,255; + @assert pixel 25,45 == 0,255,0,255; + @assert pixel 25,46 == 0,255,0,255; + @assert pixel 75,4 == 0,255,0,255; + @assert pixel 75,5 == 0,255,0,255; + @assert pixel 75,6 == 0,255,0,255; + @assert pixel 75,44 == 0,255,0,255; + @assert pixel 75,45 == 0,255,0,255; + @assert pixel 75,46 == 0,255,0,255; + +- name: 2d.line.cap.open + desc: Line caps are drawn at the corners of an unclosed rectangle + testing: + - 2d.lineCap.end + code: | + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.lineTo(200, 200); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.cap.closed + desc: Line caps are not drawn at the corners of an unclosed rectangle + testing: + - 2d.lineCap.end + code: | + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.closePath(); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.cap.valid + desc: Setting lineCap to valid values works + testing: + - 2d.lineCap.set + - 2d.lineCap.get + code: | + ctx.lineCap = 'butt' + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'round'; + @assert ctx.lineCap === 'round'; + ctx.lineCap = 'square'; + @assert ctx.lineCap === 'square'; + +- name: 2d.line.cap.invalid + desc: Setting lineCap to invalid values is ignored + testing: + - 2d.lineCap.invalid + code: | + ctx.lineCap = 'butt' + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = 'invalid'; + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = 'ROUND'; + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = 'round\0'; + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = 'round '; + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = ""; + @assert ctx.lineCap === 'butt'; + ctx.lineCap = 'butt'; + ctx.lineCap = 'bevel'; + @assert ctx.lineCap === 'butt'; + +- name: 2d.line.join.bevel + desc: lineJoin 'bevel' is rendered correctly + testing: + - 2d.lineJoin.common + - 2d.lineJoin.bevel + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var tol = 1; // tolerance to avoid antialiasing artifacts + ctx.lineJoin = 'bevel'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.lineTo(40-tol, 20); + ctx.lineTo(30, 10+tol); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.lineTo(90+tol, 20); + ctx.lineTo(80, 10-tol); + ctx.fill(); + @assert pixel 34,16 == 0,255,0,255; + @assert pixel 34,15 == 0,255,0,255; + @assert pixel 35,15 == 0,255,0,255; + @assert pixel 36,15 == 0,255,0,255; + @assert pixel 36,14 == 0,255,0,255; + @assert pixel 84,16 == 0,255,0,255; + @assert pixel 84,15 == 0,255,0,255; + @assert pixel 85,15 == 0,255,0,255; + @assert pixel 86,15 == 0,255,0,255; + @assert pixel 86,14 == 0,255,0,255; + +- name: 2d.line.join.round + desc: lineJoin 'round' is rendered correctly + testing: + - 2d.lineJoin.round + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var tol = 1; // tolerance to avoid antialiasing artifacts + ctx.lineJoin = 'round'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true); + ctx.fill(); + @assert pixel 36,14 == 0,255,0,255; + @assert pixel 36,13 == 0,255,0,255; + @assert pixel 37,13 == 0,255,0,255; + @assert pixel 38,13 == 0,255,0,255; + @assert pixel 38,12 == 0,255,0,255; + @assert pixel 86,14 == 0,255,0,255; + @assert pixel 86,13 == 0,255,0,255; + @assert pixel 87,13 == 0,255,0,255; + @assert pixel 88,13 == 0,255,0,255; + @assert pixel 88,12 == 0,255,0,255; + +- name: 2d.line.join.miter + desc: lineJoin 'miter' is rendered correctly + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineJoin = 'miter'; + ctx.lineWidth = 20; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(10, 10, 30, 20); + ctx.fillRect(20, 10, 20, 30); + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + ctx.fillRect(60, 10, 30, 20); + ctx.fillRect(70, 10, 20, 30); + @assert pixel 38,12 == 0,255,0,255; + @assert pixel 39,11 == 0,255,0,255; + @assert pixel 40,10 == 0,255,0,255; + @assert pixel 41,9 == 0,255,0,255; + @assert pixel 42,8 == 0,255,0,255; + @assert pixel 88,12 == 0,255,0,255; + @assert pixel 89,11 == 0,255,0,255; + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 91,9 == 0,255,0,255; + @assert pixel 92,8 == 0,255,0,255; + +- name: 2d.line.join.open + desc: Line joins are not drawn at the corner of an unclosed rectangle + testing: + - 2d.lineJoin.joins + code: | + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.lineTo(100, 50); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.join.closed + desc: Line joins are drawn at the corner of a closed rectangle + testing: + - 2d.lineJoin.joinclosed + code: | + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.closePath(); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.join.parallel + desc: Line joins are drawn at 180-degree joins + testing: + - 2d.lineJoin.joins + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 300; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.lineTo(0, 25); + ctx.lineTo(-100, 25); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.join.valid + desc: Setting lineJoin to valid values works + testing: + - 2d.lineJoin.set + - 2d.lineJoin.get + code: | + ctx.lineJoin = 'bevel' + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'round'; + @assert ctx.lineJoin === 'round'; + ctx.lineJoin = 'miter'; + @assert ctx.lineJoin === 'miter'; + +- name: 2d.line.join.invalid + desc: Setting lineJoin to invalid values is ignored + testing: + - 2d.lineJoin.invalid + code: | + ctx.lineJoin = 'bevel' + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'invalid'; + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'ROUND'; + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round\0'; + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round '; + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = ""; + @assert ctx.lineJoin === 'bevel'; + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'butt'; + @assert ctx.lineJoin === 'bevel'; + +- name: 2d.line.miter.exceeded + desc: Miter joins are not drawn when the miter limit is exceeded + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.acute + desc: Miter joins are drawn correctly with acute angles + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 2.614; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 2.613; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.obtuse + desc: Miter joins are drawn correctly with obtuse angles + testing: + - 2d.lineJoin.miterLimit + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 1600; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.083; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.082; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.rightangle + desc: Miter joins are not drawn when the miter limit is exceeded, on exact right angles + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 200); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.lineedge + desc: Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.strokeRect(100, 25, 200, 0); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.within + desc: Miter joins are drawn when the miter limit is not quite exceeded + testing: + - 2d.lineJoin.miter + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.416; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.miter.valid + desc: Setting miterLimit to valid values works + testing: + - 2d.miterLimit.set + - 2d.miterLimit.get + code: | + ctx.miterLimit = 1.5; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = "1e1"; + @assert ctx.miterLimit === 10; + ctx.miterLimit = 1/1024; + @assert ctx.miterLimit === 1/1024; + ctx.miterLimit = 1000; + @assert ctx.miterLimit === 1000; + +- name: 2d.line.miter.invalid + desc: Setting miterLimit to invalid values is ignored + testing: + - 2d.miterLimit.invalid + code: | + ctx.miterLimit = 1.5; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = 1.5; + ctx.miterLimit = 0; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = 1.5; + ctx.miterLimit = -1; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = 1.5; + ctx.miterLimit = Infinity; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = 1.5; + ctx.miterLimit = -Infinity; + @assert ctx.miterLimit === 1.5; + ctx.miterLimit = 1.5; + ctx.miterLimit = NaN; + @assert ctx.miterLimit === 1.5; + +- name: 2d.line.cross + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.lineJoin = 'bevel'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(110, 50); + ctx.lineTo(110, 60); + ctx.lineTo(100, 60); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + +- name: 2d.line.union + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 24); + ctx.lineTo(100, 25); + ctx.lineTo(0, 26); + ctx.closePath(); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 25,1 == 0,255,0,255; + @assert pixel 48,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 25,1 == 0,255,0,255; + @assert pixel 48,48 == 0,255,0,255; + +- name: 2d.path.initial + testing: + - 2d.path.initial + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.beginPath + testing: + - 2d.path.beginPath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.moveTo.basic + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 10, 50); + ctx.moveTo(100, 0); + ctx.lineTo(10, 0); + ctx.lineTo(10, 50); + ctx.lineTo(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 90,25 == 0,255,0,255; + +- name: 2d.path.moveTo.newsubpath + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.moveTo(100, 0); + ctx.moveTo(100, 50); + ctx.moveTo(0, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.moveTo.multiple + testing: + - 2d.path.moveTo + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 25); + ctx.moveTo(100, 25); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.moveTo.nonfinite + desc: moveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.moveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.closePath.empty + testing: + - 2d.path.closePath.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.closePath.newline + testing: + - 2d.path.closePath.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.closePath(); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.closePath.nextpoint + testing: + - 2d.path.closePath.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -1000); + ctx.closePath(); + ctx.lineTo(1000, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.lineTo.ensuresubpath.1 + desc: If there is no subpath, the point is added and nothing is drawn + testing: + - 2d.path.lineTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(100, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.lineTo.ensuresubpath.2 + desc: If there is no subpath, the point is added and used for subsequent drawing + testing: + - 2d.path.lineTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.lineTo.basic + testing: + - 2d.path.lineTo.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.lineTo.nextpoint + testing: + - 2d.path.lineTo.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.lineTo.nonfinite + desc: lineTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.lineTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + +- name: 2d.path.lineTo.nonfinite.details + desc: lineTo() with Infinity/NaN for first arg still converts the second arg + testing: + - 2d.nonfinite + code: | + for (var arg1 of [Infinity, -Infinity, NaN]) { + var converted = false; + ctx.lineTo(arg1, { valueOf: function() { converted = true; return 0; } }); + @assert converted; + } + +- name: 2d.path.quadraticCurveTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.quadratic.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(100, 50, 200, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 95,45 == 0,255,0,255; @moz-todo + +- name: 2d.path.quadraticCurveTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.quadratic.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(0, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; @moz-todo + +- name: 2d.path.quadraticCurveTo.basic + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.quadraticCurveTo(100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.quadraticCurveTo.shape + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-1000, 1050); + ctx.quadraticCurveTo(0, -1000, 1200, 1050); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.quadraticCurveTo.scaled + testing: + - 2d.path.quadratic.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-1, 1.05); + ctx.quadraticCurveTo(0, -1, 1.2, 1.05); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.quadraticCurveTo.nonfinite + desc: quadraticCurveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.quadraticCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.bezier.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(100, 50, 200, 50, 200, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 95,45 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.bezier.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(0, 25, 100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 5,45 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.basic + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.bezierCurveTo(100, 25, 100, 25, 100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.shape + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-2000, 3100); + ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.scaled + testing: + - 2d.path.bezier.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-2, 3.1); + ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.bezierCurveTo.nonfinite + desc: bezierCurveTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.bezierCurveTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + +- name: 2d.path.arcTo.ensuresubpath.1 + desc: If there is no subpath, the first control point is added (and nothing is drawn up to it) + testing: + - 2d.path.arcTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arcTo(100, 50, 200, 50, 0.1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.ensuresubpath.2 + desc: If there is no subpath, the first control point is added + testing: + - 2d.path.arcTo.empty + - 2d.path.ensure + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arcTo(0, 25, 50, 250, 0.1); // adds (x1,y1), draws nothing + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.coincide.1 + desc: arcTo() has no effect if P0 = P1 + testing: + - 2d.path.arcTo.coincide.01 + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(0, 25, 50, 1000, 1); + ctx.lineTo(100, 25); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 100, 25, 1); + ctx.stroke(); + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + +- name: 2d.path.arcTo.coincide.2 + desc: arcTo() draws a straight line to P1 if P1 = P2 + testing: + - 2d.path.arcTo.coincide.12 + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 25, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.collinear.1 + desc: arcTo() with all points on a line, and P1 between P0/P2, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 200, 25, 1); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, 100, 25, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.collinear.2 + desc: arcTo() with all points on a line, and P2 between P0/P1, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 10, 25, 1); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 110, 25, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.collinear.3 + desc: arcTo() with all points on a line, and P0 between P1/P2, draws a straight line to P1 + testing: + - 2d.path.arcTo.collinear + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 1); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 0, 25, 1); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, -200, 25, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.shape.curve1 + desc: arcTo() curves in the right kind of shape + testing: + - 2d.path.arcTo.shape + code: | + var tol = 1.5; // tolerance to avoid antialiasing artifacts + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 55,19 == 0,255,0,255; + @assert pixel 55,20 == 0,255,0,255; + @assert pixel 55,21 == 0,255,0,255; + @assert pixel 64,22 == 0,255,0,255; + @assert pixel 65,21 == 0,255,0,255; + @assert pixel 72,28 == 0,255,0,255; + @assert pixel 73,27 == 0,255,0,255; + @assert pixel 78,36 == 0,255,0,255; + @assert pixel 79,35 == 0,255,0,255; + @assert pixel 80,44 == 0,255,0,255; + @assert pixel 80,45 == 0,255,0,255; + @assert pixel 80,46 == 0,255,0,255; + @assert pixel 65,45 == 0,255,0,255; + +- name: 2d.path.arcTo.shape.curve2 + desc: arcTo() curves in the right kind of shape + testing: + - 2d.path.arcTo.shape + code: | + var tol = 1.5; // tolerance to avoid antialiasing artifacts + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false); + ctx.fill(); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 55,19 == 0,255,0,255; + @assert pixel 55,20 == 0,255,0,255; + @assert pixel 55,21 == 0,255,0,255; + @assert pixel 64,22 == 0,255,0,255; + @assert pixel 65,21 == 0,255,0,255; + @assert pixel 72,28 == 0,255,0,255; + @assert pixel 73,27 == 0,255,0,255; + @assert pixel 78,36 == 0,255,0,255; + @assert pixel 79,35 == 0,255,0,255; + @assert pixel 80,44 == 0,255,0,255; + @assert pixel 80,45 == 0,255,0,255; + @assert pixel 80,46 == 0,255,0,255; + +- name: 2d.path.arcTo.shape.start + desc: arcTo() draws a straight line from P0 to P1 + testing: + - 2d.path.arcTo.shape + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(200, 25, 200, 50, 10); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arcTo.shape.end + desc: arcTo() does not draw anything from P1 to P2 + testing: + - 2d.path.arcTo.shape + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.arcTo(-100, 25, 200, 25, 10); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arcTo.negative + desc: arcTo() with negative radius throws an exception + testing: + - 2d.path.arcTo.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.arcTo(0, 0, 0, 0, -1); + +- name: 2d.path.arcTo.zero.1 + desc: arcTo() with zero radius draws a straight line from P0 to P1 + testing: + - 2d.path.arcTo.zeroradius + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 100, 0); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(0, -25); + ctx.arcTo(50, -25, 50, 50, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.zero.2 + desc: arcTo() with zero radius draws a straight line from P0 to P1, even when all points are collinear + testing: + - 2d.path.arcTo.zeroradius + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 0); + ctx.stroke(); + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 50, 25, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arcTo.transformation + desc: arcTo joins up to the last subpath point correctly + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-100, 0); + ctx.fill(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.arcTo.scale + desc: arcTo scales the curve, not just the control points + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.scale(0.1, 1); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-1000, 0); + ctx.fill(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.arcTo.nonfinite + desc: arcTo() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.arcTo(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + + +- name: 2d.path.arc.empty + desc: arc() with an empty path does not draw a straight line to the start point + testing: + - 2d.path.arc.nonempty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.nonempty + desc: arc() with a non-empty path does draw a straight line to the start point + testing: + - 2d.path.arc.nonempty + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.end + desc: arc() adds the end point of the arc to the subpath + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(-100, 0); + ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true); + ctx.lineTo(100, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.default + desc: arc() with missing last argument defaults to clockwise + testing: + - 2d.path.arc.omitted + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, -Math.PI, Math.PI/2); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.angle.1 + desc: arc() draws pi/2 .. -pi anticlockwise correctly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.angle.2 + desc: arc() draws -3pi/2 .. -pi anticlockwise correctly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.angle.3 + desc: arc() wraps angles mod 2pi when anticlockwise and end > start+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.angle.4 + desc: arc() draws a full circle when clockwise and end > start+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false); + ctx.fill(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.angle.5 + desc: arc() wraps angles mod 2pi when clockwise and start > end+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.angle.6 + desc: arc() draws a full circle when anticlockwise and start > end+2pi + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true); + ctx.fill(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.zero.1 + desc: arc() draws nothing when startAngle = endAngle and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.zero.2 + desc: arc() draws nothing when startAngle = endAngle and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.twopie.1 + desc: arc() draws nothing when end = start + 2pi-e and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.twopie.2 + desc: arc() draws a full circle when end = start + 2pi-e and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.twopie.3 + desc: arc() draws a full circle when end = start + 2pi+e and anticlockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.twopie.4 + desc: arc() draws nothing when end = start + 2pi+e and clockwise + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false); + ctx.stroke(); + @assert pixel 50,20 == 0,255,0,255; + +- name: 2d.path.arc.shape.1 + desc: arc() from 0 to pi does not draw anything in the wrong half + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 20,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.shape.2 + desc: arc() from 0 to pi draws stuff in the right half + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 20,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.shape.3 + desc: arc() from 0 to -pi/2 does not draw anything in the wrong quadrant + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(0, 50, 50, 0, -Math.PI/2, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; @moz-todo + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.shape.4 + desc: arc() from 0 to -pi/2 draws stuff in the right quadrant + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 150; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 100, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.shape.5 + desc: arc() from 0 to 5pi does not draw crazy things + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(300, 0, 100, 0, 5*Math.PI, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.selfintersect.1 + desc: arc() with lineWidth > 2*radius is drawn sensibly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(100, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(0, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; @moz-todo + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.selfintersect.2 + desc: arc() with lineWidth > 2*radius is drawn sensibly + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 180; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(100, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 97,1 == 0,255,0,255; + @assert pixel 97,2 == 0,255,0,255; + @assert pixel 97,3 == 0,255,0,255; + @assert pixel 2,48 == 0,255,0,255; + +- name: 2d.path.arc.negative + desc: arc() with negative radius throws INDEX_SIZE_ERR + testing: + - 2d.path.arc.negative + code: | + @assert throws INDEX_SIZE_ERR ctx.arc(0, 0, -1, 0, 0, true); + +- name: 2d.path.arc.zeroradius + desc: arc() with zero radius draws a line to the start point + testing: + - 2d.path.arc.zero + code: | + ctx.fillStyle = '#f00' + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 0, 0, Math.PI, true); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.arc.scale.1 + desc: Non-uniformly scaled arcs are the right shape + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(2, 0.5); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(25, 50, 56, 0, 2*Math.PI, false); + ctx.fill(); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-25, 50); + ctx.arc(-25, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(75, 50); + ctx.arc(75, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, -25); + ctx.arc(25, -25, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, 125); + ctx.arc(25, 125, 24, 0, 2*Math.PI, false); + ctx.fill(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.arc.scale.2 + desc: Highly scaled arcs are the right shape + testing: + - 2d.path.arc.draw + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(100, 100); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 1.2; + ctx.beginPath(); + ctx.arc(0, 0, 0.6, 0, Math.PI/2, false); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 50,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 98,25 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 50,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.arc.nonfinite + desc: arc() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.arc(<0 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <0 Infinity -Infinity NaN>, <2*Math.PI Infinity -Infinity NaN>, <true>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + + +- name: 2d.path.rect.basic + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 100, 50); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.newsubpath + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-50, 25); + ctx.rect(200, 25, 1, 1); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.closed + testing: + - 2d.path.rect.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.rect(100, 50, 100, 100); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.end.1 + testing: + - 2d.path.rect.newsubpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.rect(200, 100, 400, 1000); + ctx.lineTo(-2000, -1000); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.end.2 + testing: + - 2d.path.rect.newsubpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 450; + ctx.lineCap = 'round'; + ctx.lineJoin = 'bevel'; + ctx.rect(150, 150, 2000, 2000); + ctx.lineTo(160, 160); + ctx.stroke(); + @assert pixel 1,1 == 0,255,0,255; + @assert pixel 98,1 == 0,255,0,255; + @assert pixel 1,48 == 0,255,0,255; + @assert pixel 98,48 == 0,255,0,255; + +- name: 2d.path.rect.zero.1 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(0, 50, 100, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.zero.2 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, -100, 0, 250); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.zero.3 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.zero.4 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.rect(100, 25, 0, 0); + ctx.lineTo(0, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.zero.5 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(0, 0); + ctx.rect(100, 25, 0, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.rect.zero.6 + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.5; + ctx.lineWidth = 200; + ctx.beginPath(); + ctx.rect(100, 25, 1000, 0); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.rect.negative + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 50, 25); + ctx.rect(100, 0, -50, 25); + ctx.rect(0, 50, 50, -25); + ctx.rect(100, 50, -50, -25); + ctx.fill(); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.path.rect.winding + testing: + - 2d.path.rect.subpath + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.rect(0, 0, 50, 50); + ctx.rect(100, 50, -50, -50); + ctx.rect(0, 25, 100, -25); + ctx.rect(100, 25, -100, 25); + ctx.fill(); + @assert pixel 25,12 == 0,255,0,255; + @assert pixel 75,12 == 0,255,0,255; + @assert pixel 25,37 == 0,255,0,255; + @assert pixel 75,37 == 0,255,0,255; + +- name: 2d.path.rect.selfintersect + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 90; + ctx.beginPath(); + ctx.rect(45, 20, 10, 10); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.rect.nonfinite + desc: rect() with Infinity/NaN is ignored + testing: + - 2d.nonfinite + code: | + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + @nonfinite ctx.rect(<0 Infinity -Infinity NaN>, <50 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>, <1 Infinity -Infinity NaN>); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 90,45 == 0,255,0,255; + +- name: 2d.path.fill.overlap + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.rect(0, 0, 100, 50); + ctx.closePath(); + ctx.rect(10, 10, 80, 30); + ctx.fill(); + @assert pixel 50,25 ==~ 0,127,0,255 +/- 1; + +- name: 2d.path.fill.winding.add + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.fill.winding.subtract.1 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.fill.winding.subtract.2 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.fill.winding.subtract.3 + testing: + - 2d.path.fill.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(-20, -20); + ctx.lineTo(120, -20); + ctx.lineTo(120, 70); + ctx.lineTo(-20, 70); + ctx.lineTo(-20, -20); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.fill.closed.basic + testing: + - 2d.path.fill.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.fill.closed.unaffected + testing: + - 2d.path.fill.closed + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 90,10 == 0,255,0,255; + @assert pixel 10,40 == 0,255,0,255; + +- name: 2d.path.stroke.overlap + desc: Stroked subpaths are combined before being drawn + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.lineWidth = 50; + ctx.moveTo(0, 20); + ctx.lineTo(100, 20); + ctx.moveTo(0, 30); + ctx.lineTo(100, 30); + ctx.stroke(); + @assert pixel 50,25 ==~ 0,127,0,255 +/- 1; + +- name: 2d.path.stroke.union + desc: Strokes in opposite directions are unioned, not subtracted + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 40; + ctx.moveTo(0, 10); + ctx.lineTo(100, 10); + ctx.moveTo(100, 40); + ctx.lineTo(0, 40); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.stroke.unaffected + desc: Stroking does not start a new path or subpath + testing: + - 2d.path.stroke.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.closePath(); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.stroke.scale1 + desc: Stroke line widths are scaled by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.stroke.scale2 + desc: Stroke line widths are scaled by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.stroke.skew + desc: Strokes lines are skewed by the current transformation matrix + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.beginPath(); + ctx.moveTo(49, -50); + ctx.lineTo(201, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 283); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + @assert pixel 0,0 == 0,255,0,255; + @assert pixel 50,0 == 0,255,0,255; + @assert pixel 99,0 == 0,255,0,255; + @assert pixel 0,25 == 0,255,0,255; + @assert pixel 50,25 == 0,255,0,255; + @assert pixel 99,25 == 0,255,0,255; + @assert pixel 0,49 == 0,255,0,255; + @assert pixel 50,49 == 0,255,0,255; + @assert pixel 99,49 == 0,255,0,255; + +- name: 2d.path.stroke.empty + desc: Empty subpaths are not stroked + testing: + - 2d.path.stroke.empty + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(40, 25); + ctx.moveTo(60, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.stroke.prune.line + desc: Zero-length line segments from lineTo are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.stroke.prune.closed + desc: Zero-length line segments from closed paths are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.closePath(); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.stroke.prune.curve + desc: Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.quadraticCurveTo(50, 25, 50, 25); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.stroke.prune.arc + desc: Zero-length line segments from arcTo and arc are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 150, 25, 10); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(60, 25); + ctx.arc(50, 25, 10, 0, 0, false); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.stroke.prune.rect + desc: Zero-length line segments from rect and strokeRect are removed before stroking + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + ctx.strokeRect(50, 25, 0, 0); + @assert pixel 50,25 == 0,255,0,255; @moz-todo + +- name: 2d.path.stroke.prune.corner + desc: Zero-length line segments are removed before stroking with miters + testing: + - 2d.path.stroke.prune + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.4; + ctx.beginPath(); + ctx.moveTo(-1000, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 1000); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.transformation.basic + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(-100, 0); + ctx.rect(100, 0, 100, 50); + ctx.translate(0, -100); + ctx.fillStyle = '#0f0'; + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.transformation.multiple + desc: Transformations are applied while building paths, not when drawing + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.translate(-100, 0); + ctx.rect(0, 0, 100, 50); + ctx.fill(); + ctx.translate(100, 0); + ctx.fill(); + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.translate(0, -50); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + ctx.translate(0, 50); + ctx.stroke(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.transformation.changing + desc: Transformations are applied while building paths, not when drawing + testing: + - 2d.path.transformation + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.translate(100, 0); + ctx.lineTo(0, 0); + ctx.translate(0, 50); + ctx.lineTo(0, 0); + ctx.translate(-100, 0); + ctx.lineTo(0, 0); + ctx.translate(1000, 1000); + ctx.rotate(Math.PI/2); + ctx.scale(0.1, 0.1); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.empty + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.basic.1 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clip(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.basic.2 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(-100, 0, 100, 50); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.intersect + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.beginPath(); + ctx.rect(50, 0, 50, 50) + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.winding.1 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.winding.2 + testing: + - 2d.path.clip.basic + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.clip(); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.lineTo(0, 0); + ctx.clip(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.clip.unaffected + testing: + - 2d.path.clip.closed + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + ctx.lineTo(0, 0); + ctx.fill(); + @assert pixel 50,25 == 0,255,0,255; + +- name: 2d.path.isPointInPath.basic.1 + desc: isPointInPath() detects whether the point is inside the path + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === true; + @assert ctx.isPointInPath(30, 10) === false; + +- name: 2d.path.isPointInPath.basic.2 + desc: isPointInPath() detects whether the point is inside the path + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(20, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(30, 10) === true; + +- name: 2d.path.isPointInPath.edge + desc: isPointInPath() counts points on the path as being inside + testing: + - 2d.path.isPointInPath.edge + code: | + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(0, 0) === true; + @assert ctx.isPointInPath(10, 0) === true; + @assert ctx.isPointInPath(20, 0) === true; + @assert ctx.isPointInPath(20, 10) === true; + @assert ctx.isPointInPath(20, 20) === true; + @assert ctx.isPointInPath(10, 20) === true; + @assert ctx.isPointInPath(0, 20) === true; + @assert ctx.isPointInPath(0, 10) === true; + @assert ctx.isPointInPath(10, -0.01) === false; + @assert ctx.isPointInPath(10, 20.01) === false; + @assert ctx.isPointInPath(-0.01, 10) === false; + @assert ctx.isPointInPath(20.01, 10) === false; + +- name: 2d.path.isPointInPath.empty + desc: isPointInPath() works when there is no path + testing: + - 2d.path.isPointInPath + code: | + @assert ctx.isPointInPath(0, 0) === false; + +- name: 2d.path.isPointInPath.subpath + desc: isPointInPath() uses the current path, not just the subpath + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, 0, 20, 20); + ctx.beginPath(); + ctx.rect(20, 0, 20, 20); + ctx.closePath(); + ctx.rect(40, 0, 20, 20); + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(30, 10) === true; + @assert ctx.isPointInPath(50, 10) === true; + +- name: 2d.path.isPointInPath.outside + desc: isPointInPath() works on paths outside the canvas + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(0, -100, 20, 20); + ctx.rect(20, -10, 20, 20); + @assert ctx.isPointInPath(10, -110) === false; + @assert ctx.isPointInPath(10, -90) === true; + @assert ctx.isPointInPath(10, -70) === false; + @assert ctx.isPointInPath(30, -20) === false; + @assert ctx.isPointInPath(30, 0) === true; + @assert ctx.isPointInPath(30, 20) === false; + +- name: 2d.path.isPointInPath.unclosed + desc: isPointInPath() works on unclosed subpaths + testing: + - 2d.path.isPointInPath + code: | + ctx.moveTo(0, 0); + ctx.lineTo(20, 0); + ctx.lineTo(20, 20); + ctx.lineTo(0, 20); + @assert ctx.isPointInPath(10, 10) === true; + @assert ctx.isPointInPath(30, 10) === false; + +- name: 2d.path.isPointInPath.arc + desc: isPointInPath() works on arcs + testing: + - 2d.path.isPointInPath + code: | + ctx.arc(50, 25, 10, 0, Math.PI, false); + @assert ctx.isPointInPath(50, 10) === false; + @assert ctx.isPointInPath(50, 20) === false; + @assert ctx.isPointInPath(50, 30) === true; + @assert ctx.isPointInPath(50, 40) === false; + @assert ctx.isPointInPath(30, 20) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(70, 30) === false; + +- name: 2d.path.isPointInPath.bigarc + desc: isPointInPath() works on unclosed arcs larger than 2pi + opera: { bug: 320937 } + testing: + - 2d.path.isPointInPath + code: | + ctx.arc(50, 25, 10, 0, 7, false); + @assert ctx.isPointInPath(50, 10) === false; + @assert ctx.isPointInPath(50, 20) === true; + @assert ctx.isPointInPath(50, 30) === true; + @assert ctx.isPointInPath(50, 40) === false; + @assert ctx.isPointInPath(30, 20) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(70, 30) === false; + +- name: 2d.path.isPointInPath.bezier + desc: isPointInPath() works on Bezier curves + testing: + - 2d.path.isPointInPath + code: | + ctx.moveTo(25, 25); + ctx.bezierCurveTo(50, -50, 50, 100, 75, 25); + @assert ctx.isPointInPath(25, 20) === false; + @assert ctx.isPointInPath(25, 30) === false; + @assert ctx.isPointInPath(30, 20) === true; + @assert ctx.isPointInPath(30, 30) === false; + @assert ctx.isPointInPath(40, 2) === false; + @assert ctx.isPointInPath(40, 20) === true; + @assert ctx.isPointInPath(40, 30) === false; + @assert ctx.isPointInPath(40, 47) === false; + @assert ctx.isPointInPath(45, 20) === true; + @assert ctx.isPointInPath(45, 30) === false; + @assert ctx.isPointInPath(55, 20) === false; + @assert ctx.isPointInPath(55, 30) === true; + @assert ctx.isPointInPath(60, 2) === false; + @assert ctx.isPointInPath(60, 20) === false; + @assert ctx.isPointInPath(60, 30) === true; + @assert ctx.isPointInPath(60, 47) === false; + @assert ctx.isPointInPath(70, 20) === false; + @assert ctx.isPointInPath(70, 30) === true; + @assert ctx.isPointInPath(75, 20) === false; + @assert ctx.isPointInPath(75, 30) === false; + +- name: 2d.path.isPointInPath.winding + desc: isPointInPath() uses the non-zero winding number rule + testing: + - 2d.path.isPointInPath + code: | + // Create a square ring, using opposite windings to make a hole in the centre + ctx.moveTo(0, 0); + ctx.lineTo(50, 0); + ctx.lineTo(50, 50); + ctx.lineTo(0, 50); + ctx.lineTo(0, 0); + ctx.lineTo(10, 10); + ctx.lineTo(10, 40); + ctx.lineTo(40, 40); + ctx.lineTo(40, 10); + ctx.lineTo(10, 10); + @assert ctx.isPointInPath(5, 5) === true; + @assert ctx.isPointInPath(25, 5) === true; + @assert ctx.isPointInPath(45, 5) === true; + @assert ctx.isPointInPath(5, 25) === true; + @assert ctx.isPointInPath(25, 25) === false; + @assert ctx.isPointInPath(45, 25) === true; + @assert ctx.isPointInPath(5, 45) === true; + @assert ctx.isPointInPath(25, 45) === true; + @assert ctx.isPointInPath(45, 45) === true; + +- name: 2d.path.isPointInPath.transform.1 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.translate(50, 0); + ctx.rect(0, 0, 20, 20); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.2 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.rect(50, 0, 20, 20); + ctx.translate(50, 0); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.3 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.scale(-1, 1); + ctx.rect(-70, 0, 20, 20); + @assert ctx.isPointInPath(-40, 10) === false; + @assert ctx.isPointInPath(10, 10) === false; + @assert ctx.isPointInPath(49, 10) === false; + @assert ctx.isPointInPath(51, 10) === true; + @assert ctx.isPointInPath(69, 10) === true; + @assert ctx.isPointInPath(71, 10) === false; + +- name: 2d.path.isPointInPath.transform.4 + desc: isPointInPath() handles transformations correctly + testing: + - 2d.path.isPointInPath + code: | + ctx.translate(50, 0); + ctx.rect(50, 0, 20, 20); + ctx.translate(0, 50); + @assert ctx.isPointInPath(60, 10) === false; + @assert ctx.isPointInPath(110, 10) === true; + @assert ctx.isPointInPath(110, 60) === false; + +- name: 2d.path.isPointInPath.nonfinite + desc: isPointInPath() returns false for non-finite arguments + testing: + - 2d.path.isPointInPath.nonfinite + code: | + ctx.rect(-100, -50, 200, 100); + @assert ctx.isPointInPath(Infinity, 0) === false; + @assert ctx.isPointInPath(-Infinity, 0) === false; + @assert ctx.isPointInPath(NaN, 0) === false; + @assert ctx.isPointInPath(0, Infinity) === false; + @assert ctx.isPointInPath(0, -Infinity) === false; + @assert ctx.isPointInPath(0, NaN) === false; + @assert ctx.isPointInPath(NaN, NaN) === false; + +- name: 2d.coordinatespace + desc: Coordinate space goes from top-left to bottom-right + notes: This should not be upside down. + testing: + - 2d.coordinatespace + code: | + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0ff'; + ctx.fillRect(0, 0, 50, 25); + @assert pixel 25,12 == 0,255,255,255; + @assert pixel 75,12 == 0,0,255,255; + @assert pixel 25,37 == 0,0,255,255; + @assert pixel 75,37 == 0,0,255,255; + +- name: 2d.missingargs + desc: Missing arguments cause TypeError + code: | + @assert throws TypeError ctx.scale(); + @assert throws TypeError ctx.scale(1); + @assert throws TypeError ctx.rotate(); + @assert throws TypeError ctx.translate(); + @assert throws TypeError ctx.translate(0); + if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported) + @assert throws TypeError ctx.transform(); + @assert throws TypeError ctx.transform(1); + @assert throws TypeError ctx.transform(1, 0); + @assert throws TypeError ctx.transform(1, 0, 0); + @assert throws TypeError ctx.transform(1, 0, 0, 1); + @assert throws TypeError ctx.transform(1, 0, 0, 1, 0); + } + if (ctx.setTransform) { + @assert throws TypeError ctx.setTransform(); + @assert throws TypeError ctx.setTransform(1); + @assert throws TypeError ctx.setTransform(1, 0); + @assert throws TypeError ctx.setTransform(1, 0, 0); + @assert throws TypeError ctx.setTransform(1, 0, 0, 1); + @assert throws TypeError ctx.setTransform(1, 0, 0, 1, 0); + } + @assert throws TypeError ctx.createLinearGradient(); + @assert throws TypeError ctx.createLinearGradient(0); + @assert throws TypeError ctx.createLinearGradient(0, 0); + @assert throws TypeError ctx.createLinearGradient(0, 0, 1); + @assert throws TypeError ctx.createRadialGradient(); + @assert throws TypeError ctx.createRadialGradient(0); + @assert throws TypeError ctx.createRadialGradient(0, 0); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0); + @assert throws TypeError ctx.createRadialGradient(0, 0, 1, 0, 0); + @assert throws TypeError ctx.createPattern(offscreenCanvas); + @assert throws TypeError ctx.clearRect(); + @assert throws TypeError ctx.clearRect(0); + @assert throws TypeError ctx.clearRect(0, 0); + @assert throws TypeError ctx.clearRect(0, 0, 0); + @assert throws TypeError ctx.fillRect(); + @assert throws TypeError ctx.fillRect(0); + @assert throws TypeError ctx.fillRect(0, 0); + @assert throws TypeError ctx.fillRect(0, 0, 0); + @assert throws TypeError ctx.strokeRect(); + @assert throws TypeError ctx.strokeRect(0); + @assert throws TypeError ctx.strokeRect(0, 0); + @assert throws TypeError ctx.strokeRect(0, 0, 0); + @assert throws TypeError ctx.moveTo(); + @assert throws TypeError ctx.moveTo(0); + @assert throws TypeError ctx.lineTo(); + @assert throws TypeError ctx.lineTo(0); + @assert throws TypeError ctx.quadraticCurveTo(); + @assert throws TypeError ctx.quadraticCurveTo(0); + @assert throws TypeError ctx.quadraticCurveTo(0, 0); + @assert throws TypeError ctx.quadraticCurveTo(0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(); + @assert throws TypeError ctx.bezierCurveTo(0); + @assert throws TypeError ctx.bezierCurveTo(0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0); + @assert throws TypeError ctx.bezierCurveTo(0, 0, 0, 0, 0); + @assert throws TypeError ctx.arcTo(); + @assert throws TypeError ctx.arcTo(0); + @assert throws TypeError ctx.arcTo(0, 0); + @assert throws TypeError ctx.arcTo(0, 0, 0); + @assert throws TypeError ctx.arcTo(0, 0, 0, 0); + @assert throws TypeError ctx.rect(); + @assert throws TypeError ctx.rect(0); + @assert throws TypeError ctx.rect(0, 0); + @assert throws TypeError ctx.rect(0, 0, 0); + @assert throws TypeError ctx.arc(); + @assert throws TypeError ctx.arc(0); + @assert throws TypeError ctx.arc(0, 0); + @assert throws TypeError ctx.arc(0, 0, 1); + @assert throws TypeError ctx.arc(0, 0, 1, 0); + @assert throws TypeError ctx.drawImage(); + @assert throws TypeError ctx.drawImage(offscreenCanvas); + @assert throws TypeError ctx.drawImage(offscreenCanvas, 0); + // TODO: n >= 3 args on drawImage could be either a valid overload, + // or too few for another overload, or too many for another + // overload - what should happen? + if (ctx.createImageData) { + @assert throws TypeError ctx.createImageData(); + @assert throws TypeError ctx.createImageData(1); + } + if (ctx.getImageData) { + @assert throws TypeError ctx.getImageData(); + @assert throws TypeError ctx.getImageData(0); + @assert throws TypeError ctx.getImageData(0, 0); + @assert throws TypeError ctx.getImageData(0, 0, 1); + } + if (ctx.putImageData) { + var imgdata = ctx.getImageData(0, 0, 1, 1); + @assert throws TypeError ctx.putImageData(); + @assert throws TypeError ctx.putImageData(imgdata); + @assert throws TypeError ctx.putImageData(imgdata, 0); + } + var g = ctx.createLinearGradient(0, 0, 0, 0); + @assert throws TypeError g.addColorStop(); @moz-todo + @assert throws TypeError g.addColorStop(0); @moz-todo + +- name: 2d.voidreturn + desc: void methods return undefined + code: | + @assert ctx.save() === undefined; + @assert ctx.restore() === undefined; + @assert ctx.scale(1, 1) === undefined; + @assert ctx.rotate(0) === undefined; + @assert ctx.translate(0, 0) === undefined; + if (ctx.transform) { // (avoid spurious failures, since the aim here is not to test that all features are supported) + @assert ctx.transform(1, 0, 0, 1, 0, 0) === undefined; + } + if (ctx.setTransform) { + @assert ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined; + } + @assert ctx.clearRect(0, 0, 0, 0) === undefined; + @assert ctx.fillRect(0, 0, 0, 0) === undefined; + @assert ctx.strokeRect(0, 0, 0, 0) === undefined; + @assert ctx.beginPath() === undefined; + @assert ctx.closePath() === undefined; + @assert ctx.moveTo(0, 0) === undefined; + @assert ctx.lineTo(0, 0) === undefined; + @assert ctx.quadraticCurveTo(0, 0, 0, 0) === undefined; + @assert ctx.bezierCurveTo(0, 0, 0, 0, 0, 0) === undefined; + @assert ctx.arcTo(0, 0, 0, 0, 1) === undefined; + @assert ctx.rect(0, 0, 0, 0) === undefined; + @assert ctx.arc(0, 0, 1, 0, 0, true) === undefined; + @assert ctx.fill() === undefined; + @assert ctx.stroke() === undefined; + @assert ctx.clip() === undefined; + if (ctx.putImageData) { + @assert ctx.putImageData(ctx.getImageData(0, 0, 1, 1), 0, 0) === undefined; + } + @assert ctx.drawImage(offscreenCanvas, 0, 0, 1, 1, 0, 0, 0, 0) === undefined; + @assert ctx.createLinearGradient(0, 0, 0, 0).addColorStop(0, 'white') === undefined; + +- name: 2d.canvas.reference + desc: canvas refers back to its canvas + testing: + - 2d.canvas + code: | + @assert ctx.canvas === offscreenCanvas; + +- name: 2d.canvas.readonly + desc: canvas is readonly + testing: + - 2d.canvas.attribute + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + var d = ctx.canvas; + @assert offscreenCanvas2 !== d; + ctx.canvas = offscreenCanvas2; + @assert ctx.canvas === d; + +- name: 2d.getcontext.exists + desc: The 2D context is implemented + testing: + - context.2d + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert offscreenCanvas2.getContext('2d') !== null; + +- name: 2d.getcontext.extraargs + desc: The 2D context ignores extra getContext arguments + testing: + - context.2d.extraargs + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert offscreenCanvas2.getContext('2d', false, {}, [], 1, "2") !== null; + +- name: 2d.getcontext.unique + desc: getContext('2d') returns the same object + testing: + - context.unique + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert offscreenCanvas2.getContext('2d') === offscreenCanvas2.getContext('2d'); + +- name: 2d.getcontext.shared + desc: getContext('2d') returns objects which share canvas state + testing: + - context.unique + code: | + var ctx2 = offscreenCanvas.getContext('2d'); + ctx.fillStyle = '#f00'; + ctx2.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: context.emptystring + desc: getContext with empty string returns null + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext(""); + +- name: context.unrecognised.badname + desc: getContext with unrecognised context name returns null + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext('This is not an implemented context in any real browser'); + +- name: context.unrecognised.badsuffix + desc: Context name "2d" plus a suffix is unrecognised + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext("2d#"); + +- name: context.unrecognised.nullsuffix + desc: Context name "2d" plus a "\0" suffix is unrecognised + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext("2d\0"); + +- name: context.unrecognised.unicode + desc: Context name which kind of looks like "2d" is unrecognised + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext("2\uFF44"); + +- name: context.casesensitive + desc: Context name "2D" is unrecognised; matching is case sensitive + testing: + - context.unrecognised + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext('2D'); + +- name: context.arguments.missing + testing: + - canvas.getContext + code: | + var offscreenCanvas2 = new OffscreenCanvas(100, 50); + @assert throws TypeError offscreenCanvas2.getContext(); @moz-todo + + +- name: initial.colour + desc: Initial state is transparent black + testing: + - initial.colour + code: | + @assert pixel 20,20 == 0,0,0,0; + +- name: initial.reset.different + desc: Changing size resets canvas to transparent black + testing: + - initial.reset + code: | + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + offscreenCanvas.width = 50; + @assert pixel 20,20 == 0,0,0,0; + +- name: initial.reset.same + desc: Setting size (not changing the value) resets canvas to transparent black + testing: + - initial.reset + code: | + offscreenCanvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + @assert pixel 20,20 == 255,0,0,255; + offscreenCanvas.width = 100; + @assert pixel 20,20 == 0,0,0,0; + +- name: initial.reset.path + desc: Resetting the canvas state resets the current path + testing: + - initial.reset + code: | + offscreenCanvas.width = 100; + ctx.rect(0, 0, 100, 50); + offscreenCanvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fill(); + @assert pixel 20,20 == 0,0,0,0; + +- name: initial.reset.clip + desc: Resetting the canvas state resets the current clip region + testing: + - initial.reset + code: | + offscreenCanvas.width = 100; + ctx.rect(0, 0, 1, 1); + ctx.clip(); + offscreenCanvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + +- name: initial.reset.transform + desc: Resetting the canvas state resets the current transformation matrix + testing: + - initial.reset + code: | + offscreenCanvas.width = 100; + ctx.scale(0.1, 0.1); + offscreenCanvas.width = 100; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 20,20 == 0,255,0,255; + +- name: initial.reset.gradient + desc: Resetting the canvas state does not invalidate any existing gradients + testing: + - initial.reset + code: | + offscreenCanvas.width = 50; + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + offscreenCanvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: initial.reset.pattern + desc: Resetting the canvas state does not invalidate any existing patterns + testing: + - initial.reset + code: | + offscreenCanvas.width = 30; + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 30, 50); + var p = ctx.createPattern(offscreenCanvas, 'repeat-x'); + offscreenCanvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = p; + ctx.fillRect(0, 0, 100, 50); + @assert pixel 50,25 == 0,255,0,255; + +- name: size.attributes.idl.set.zero + desc: Setting width/height IDL attributes to 0 + testing: + - size.width + - size.height + code: | + offscreenCanvas.width = 0; + offscreenCanvas.height = 0; + @assert offscreenCanvas.width === 0; + @assert offscreenCanvas.height === 0; + +- name: size.attributes.idl + desc: Getting/setting width/height IDL attributes + testing: + - size.width + - size.height + webidl: + - es-unsigned-long + code: | + offscreenCanvas.width = "100"; + offscreenCanvas.height = "100"; + @assert offscreenCanvas.width === 100; + @assert offscreenCanvas.height === 100; + offscreenCanvas.width = "+1.5e2"; + offscreenCanvas.height = "0x96"; + @assert offscreenCanvas.width === 150; + @assert offscreenCanvas.height === 150; + offscreenCanvas.width = 301.999; + offscreenCanvas.height = 301.001; + @assert offscreenCanvas.width === 301; + @assert offscreenCanvas.height === 301; + offscreenCanvas.width = "400x"; + offscreenCanvas.height = "foo"; + @assert offscreenCanvas.width === 0; + @assert offscreenCanvas.height === 0; + +- name: size.attributes.default + desc: Default width/height when attributes are missing + testing: + - size.default + - size.missing + code: | + @assert offscreenCanvas.width === 100; + @assert offscreenCanvas.height === 50; + +- name: size.attributes.reflect.setidl + desc: Setting IDL attributes updates IDL and content attributes + testing: + - size.reflect + code: | + offscreenCanvas.width = 120; + offscreenCanvas.height = 60; + @assert offscreenCanvas.width === 120; + @assert offscreenCanvas.height === 60; + +- name: size.attributes.reflect.setidlzero + desc: Setting IDL attributes to 0 updates IDL and content attributes + testing: + - size.reflect + code: | + offscreenCanvas.width = 0; + offscreenCanvas.height = 0; + @assert offscreenCanvas.width === 0; + @assert offscreenCanvas.height === 0; + +- meta: | + cases = [ + ("zero", "0", 0), + ("empty", "", None), + ("onlyspace", " ", None), + ("space", " 100", 100), + ("whitespace", "\t\f100", 100), + ("plus", "+100", 100), + ("minus", "-100", None), + ("octal", "0100", 100), + ("hex", "0x100", 0x100), + ("exp", "100e1", 100e1), + ("decimal", "100.999", 100), + ("percent", "100%", 100), + ("em", "100em", 100), + ("junk", "#!?", None), + ("trailingjunk", "100#!?", 100), + ] + def gen(name, string, exp, code): + testing = ["size.nonnegativeinteger"] + if exp is None: + testing.append("size.error") + code += "offscreenCanvas.width = '%s';\noffscreenCanvas.height = '%s';\n" % (string, string) + code += "@assert offscreenCanvas.width === 100;\n@assert offscreenCanvas.height === 50;\n" + expected = None + else: + code += "offscreenCanvas.width = '%s';\noffscreenCanvas.height = '%s';\n" % (string, string) + code += "@assert offscreenCanvas.width === %s;\n@assert offscreenCanvas.height === %s;\n" % (exp, exp) + expected = None + + if exp == 0: + expected = None # can't generate zero-sized PNGs for the expected image + + return code, testing, expected + + for name, string, exp in cases: + code = "" + code, testing, expected = gen(name, string, exp, code) + tests.append( { + "name": "size.attributes.parse.%s" % name, + "desc": "Parsing of non-negative integers", + "testing": testing, + "code": code, + } ) + +- name: size.large + testing: + - size.width + - size.height + notes: Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size. + code: | + var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long" + offscreenCanvas.width = n; + offscreenCanvas.height = n; + @assert offscreenCanvas.width === n; + @assert offscreenCanvas.height === n;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/__init__.py b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/__init__.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/clean.py b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/clean.py new file mode 100755 index 0000000..715e1d6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/clean.py
@@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import os, json +from common_paths import * +import spec_validator + +def rmtree(top): + top = os.path.abspath(top) + assert top != os.path.expanduser("~") + assert len(top) > len(os.path.expanduser("~")) + assert "web-platform-tests" in top + assert "referrer-policy" in top + + for root, dirs, files in os.walk(top, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + + os.rmdir(top) + +def main(): + spec_json = load_spec_json(); + spec_validator.assert_valid_spec_json(spec_json) + + for spec in spec_json['specification']: + generated_dir = os.path.join(spec_directory, spec["name"]) + if (os.path.isdir(generated_dir)): + rmtree(generated_dir) + + if (os.path.isfile(generated_spec_json_filename)): + os.remove(generated_spec_json_filename) + +if __name__ == '__main__': + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/common_paths.py b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/common_paths.py new file mode 100644 index 0000000..dc303f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/common_paths.py
@@ -0,0 +1,52 @@ +import os, sys, json, re + +script_directory = os.path.dirname(os.path.abspath(__file__)) +generic_directory = os.path.abspath(os.path.join(script_directory, '..')) + +template_directory = os.path.abspath(os.path.join(script_directory, + '..', + 'template')) +spec_directory = os.path.abspath(os.path.join(script_directory, '..', '..')) +test_root_directory = os.path.abspath(os.path.join(script_directory, + '..', '..', '..')) + +spec_filename = os.path.join(spec_directory, "spec.src.json") +generated_spec_json_filename = os.path.join(spec_directory, "spec_json.js") + +selection_pattern = '%(delivery_method)s/' + \ + '%(origin)s/' + \ + '%(source_protocol)s-%(target_protocol)s/' + \ + '%(subresource)s/' + +test_file_path_pattern = '%(spec_name)s/' + selection_pattern + \ + '%(name)s.%(redirection)s.%(source_protocol)s.html' + + +def get_template(basename): + with open(os.path.join(template_directory, basename), "r") as f: + return f.read() + + +def read_nth_line(fp, line_number): + fp.seek(0) + for i, line in enumerate(fp): + if (i + 1) == line_number: + return line + + +def load_spec_json(): + re_error_location = re.compile('line ([0-9]+) column ([0-9]+)') + with open(spec_filename, "r") as f: + try: + spec_json = json.load(f) + except ValueError, ex: + print ex.message + match = re_error_location.search(ex.message) + if match: + line_number, column = int(match.group(1)), int(match.group(2)) + print read_nth_line(f, line_number).rstrip() + print " " * (column - 1) + "^" + + sys.exit(1) + + return spec_json
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/generate.py b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/generate.py new file mode 100755 index 0000000..10fc11c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/generate.py
@@ -0,0 +1,172 @@ +#!/usr/bin/env python + +import os, sys, json +from common_paths import * +import spec_validator +import argparse + + +def expand_test_expansion_pattern(spec_test_expansion, test_expansion_schema): + expansion = {} + for artifact in spec_test_expansion: + artifact_value = spec_test_expansion[artifact] + if artifact_value == '*': + expansion[artifact] = test_expansion_schema[artifact] + elif isinstance(artifact_value, list): + expansion[artifact] = artifact_value + else: + expansion[artifact] = [artifact_value] + + return expansion + + +def permute_expansion(expansion, selection = {}, artifact_index = 0): + artifact_order = ['delivery_method', 'redirection', 'origin', + 'source_protocol', 'target_protocol', 'subresource', + 'referrer_url', 'name'] + + if artifact_index >= len(artifact_order): + yield selection + return + + artifact_key = artifact_order[artifact_index] + + for artifact_value in expansion[artifact_key]: + selection[artifact_key] = artifact_value + for next_selection in permute_expansion(expansion, + selection, + artifact_index + 1): + yield next_selection + + +def generate_selection(selection, spec, subresource_path, + test_html_template_basename): + selection['spec_name'] = spec['name'] + selection['spec_title'] = spec['title'] + selection['spec_description'] = spec['description'] + selection['spec_specification_url'] = spec['specification_url'] + selection['subresource_path'] = subresource_path + # Oddball: it can be None, so in JS it's null. + selection['referrer_policy_json'] = json.dumps(spec['referrer_policy']) + + test_filename = test_file_path_pattern % selection + test_directory = os.path.dirname(test_filename) + full_path = os.path.join(spec_directory, test_directory) + + test_html_template = get_template(test_html_template_basename) + test_js_template = get_template("test.js.template") + disclaimer_template = get_template('disclaimer.template') + test_description_template = get_template("test_description.template") + + html_template_filename = os.path.join(template_directory, + test_html_template_basename) + generated_disclaimer = disclaimer_template \ + % {'generating_script_filename': os.path.relpath(__file__, + test_root_directory), + 'html_template_filename': os.path.relpath(html_template_filename, + test_root_directory)} + + # Adjust the template for the test invoking JS. Indent it to look nice. + selection['generated_disclaimer'] = generated_disclaimer.rstrip() + test_description_template = \ + test_description_template.rstrip().replace("\n", "\n" + " " * 33) + selection['test_description'] = test_description_template % selection + + # Adjust the template for the test invoking JS. Indent it to look nice. + indent = "\n" + " " * 6; + test_js_template = indent + test_js_template.replace("\n", indent); + selection['test_js'] = test_js_template % selection + + # Directory for the test files. + try: + os.makedirs(full_path) + except: + pass + + selection['meta_delivery_method'] = '' + + if spec['referrer_policy'] != None: + if selection['delivery_method'] == 'meta-referrer': + selection['meta_delivery_method'] = \ + '<meta name="referrer" content="%(referrer_policy)s">' % spec + elif selection['delivery_method'] == 'http-rp': + selection['meta_delivery_method'] = \ + "<!-- No meta: Referrer policy delivered via HTTP headers. -->" + test_headers_filename = test_filename + ".headers" + with open(test_headers_filename, "w") as f: + f.write('Referrer-Policy: ' + \ + '%(referrer_policy)s\n' % spec) + # TODO(kristijanburnik): Limit to WPT origins. + f.write('Access-Control-Allow-Origin: *\n') + elif selection['delivery_method'] == 'attr-referrer': + # attr-referrer is supported by the JS test wrapper. + pass + elif selection['delivery_method'] == 'rel-noreferrer': + # rel=noreferrer is supported by the JS test wrapper. + pass + else: + raise ValueError('Not implemented delivery_method: ' \ + + selection['delivery_method']) + + # Obey the lint and pretty format. + if len(selection['meta_delivery_method']) > 0: + selection['meta_delivery_method'] = "\n " + \ + selection['meta_delivery_method'] + + with open(test_filename, 'w') as f: + f.write(test_html_template % selection) + + +def generate_test_source_files(spec_json, target): + test_expansion_schema = spec_json['test_expansion_schema'] + specification = spec_json['specification'] + + spec_json_js_template = get_template('spec_json.js.template') + with open(generated_spec_json_filename, 'w') as f: + f.write(spec_json_js_template + % {'spec_json': json.dumps(spec_json)}) + + # Choose a debug/release template depending on the target. + html_template = "test.%s.html.template" % target + + # Create list of excluded tests. + exclusion_dict = {} + for excluded_pattern in spec_json['excluded_tests']: + excluded_expansion = \ + expand_test_expansion_pattern(excluded_pattern, + test_expansion_schema) + for excluded_selection in permute_expansion(excluded_expansion): + excluded_selection_path = selection_pattern % excluded_selection + exclusion_dict[excluded_selection_path] = True + + for spec in specification: + for spec_test_expansion in spec['test_expansion']: + expansion = expand_test_expansion_pattern(spec_test_expansion, + test_expansion_schema) + for selection in permute_expansion(expansion): + selection_path = selection_pattern % selection + if not selection_path in exclusion_dict: + subresource_path = \ + spec_json["subresource_path"][selection["subresource"]] + generate_selection(selection, + spec, + subresource_path, + html_template) + else: + print 'Excluding selection:', selection_path + + +def main(target): + spec_json = load_spec_json(); + spec_validator.assert_valid_spec_json(spec_json) + generate_test_source_files(spec_json, target) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Test suite generator utility') + parser.add_argument('-t', '--target', type = str, + choices = ("release", "debug"), default = "release", + help = 'Sets the appropriate template for generating tests') + # TODO(kristijanburnik): Add option for the spec_json file. + args = parser.parse_args() + main(args.target)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/regenerate b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/regenerate new file mode 100755 index 0000000..e6bd635 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/regenerate
@@ -0,0 +1,3 @@ +#!/bin/bash +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +python $DIR/clean.py && python $DIR/generate.py
diff --git a/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/spec_validator.py b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/spec_validator.py new file mode 100755 index 0000000..8641bbc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/referrer-policy/generic/tools/spec_validator.py
@@ -0,0 +1,166 @@ +#!/usr/bin/env python + +import json, sys +from common_paths import * + +def assert_non_empty_string(obj, field): + assert field in obj, 'Missing field "%s"' % field + assert isinstance(obj[field], basestring), \ + 'Field "%s" must be a string' % field + assert len(obj[field]) > 0, 'Field "%s" must not be empty' % field + +def assert_non_empty_list(obj, field): + assert isinstance(obj[field], list), \ + '%s must be a list' % field + assert len(obj[field]) > 0, \ + '%s list must not be empty' % field + +def assert_non_empty_dict(obj, field): + assert isinstance(obj[field], dict), \ + '%s must be a dict' % field + assert len(obj[field]) > 0, \ + '%s dict must not be empty' % field + +def assert_contains(obj, field): + assert field in obj, 'Must contain field "%s"' % field + +def assert_value_from(obj, field, items): + assert obj[field] in items, \ + 'Field "%s" must be from: %s' % (field, str(items)) + +def assert_atom_or_list_items_from(obj, field, items): + if isinstance(obj[field], basestring) or isinstance(obj[field], int): + assert_value_from(obj, field, items) + return + + assert_non_empty_list(obj, field) + for allowed_value in obj[field]: + assert allowed_value != '*', "Wildcard is not supported for lists!" + assert allowed_value in items, \ + 'Field "%s" must be from: %s' % (field, str(items)) + +def assert_contains_only_fields(obj, expected_fields): + for expected_field in expected_fields: + assert_contains(obj, expected_field) + + for actual_field in obj: + assert actual_field in expected_fields, \ + 'Unexpected field "%s".' % actual_field + +def assert_value_unique_in(value, used_values): + assert value not in used_values, 'Duplicate value "%s"!' % str(value) + used_values[value] = True + + +def validate(spec_json, details): + """ Validates the json specification for generating tests. """ + + details['object'] = spec_json + assert_contains_only_fields(spec_json, ["specification", + "referrer_policy_schema", + "test_expansion_schema", + "subresource_path", + "excluded_tests"]) + assert_non_empty_list(spec_json, "specification") + assert_non_empty_list(spec_json, "referrer_policy_schema") + assert_non_empty_dict(spec_json, "test_expansion_schema") + assert_non_empty_list(spec_json, "excluded_tests") + + specification = spec_json['specification'] + referrer_policy_schema = spec_json['referrer_policy_schema'] + test_expansion_schema = spec_json['test_expansion_schema'] + excluded_tests = spec_json['excluded_tests'] + subresource_path = spec_json['subresource_path'] + + valid_test_expansion_fields = ['name'] + test_expansion_schema.keys() + + # Validate each single spec. + for spec in specification: + details['object'] = spec + + # Validate required fields for a single spec. + assert_contains_only_fields(spec, ['name', + 'title', + 'description', + 'referrer_policy', + 'specification_url', + 'test_expansion']) + assert_non_empty_string(spec, 'name') + assert_non_empty_string(spec, 'title') + assert_non_empty_string(spec, 'description') + assert_non_empty_string(spec, 'specification_url') + assert_value_from(spec, 'referrer_policy', referrer_policy_schema) + assert_non_empty_list(spec, 'test_expansion') + + # Validate spec's test expansion. + used_spec_names = {} + + for spec_exp in spec['test_expansion']: + details['object'] = spec_exp + assert_non_empty_string(spec_exp, 'name') + # The name is unique in same expansion group. + assert_value_unique_in((spec_exp['expansion'], spec_exp['name']), + used_spec_names) + assert_contains_only_fields(spec_exp, valid_test_expansion_fields) + + for artifact in test_expansion_schema: + details['test_expansion_field'] = artifact + assert_atom_or_list_items_from( + spec_exp, artifact, ['*'] + test_expansion_schema[artifact]) + del details['test_expansion_field'] + + # Validate the test_expansion schema members. + details['object'] = test_expansion_schema + assert_contains_only_fields(test_expansion_schema, ['expansion', + 'delivery_method', + 'redirection', + 'origin', + 'source_protocol', + 'target_protocol', + 'subresource', + 'referrer_url']) + # Validate excluded tests. + details['object'] = excluded_tests + for excluded_test_expansion in excluded_tests: + assert_contains_only_fields(excluded_test_expansion, + valid_test_expansion_fields) + details['object'] = excluded_test_expansion + for artifact in test_expansion_schema: + details['test_expansion_field'] = artifact + assert_atom_or_list_items_from( + excluded_test_expansion, + artifact, + ['*'] + test_expansion_schema[artifact]) + del details['test_expansion_field'] + + # Validate subresource paths. + details['object'] = subresource_path + assert_contains_only_fields(subresource_path, + test_expansion_schema['subresource']); + + for subresource in subresource_path: + local_rel_path = "." + subresource_path[subresource] + full_path = os.path.join(test_root_directory, local_rel_path) + assert os.path.isfile(full_path), "%s is not an existing file" % path + + del details['object'] + + +def assert_valid_spec_json(spec_json): + error_details = {} + try: + validate(spec_json, error_details) + except AssertionError, err: + print 'ERROR:', err.message + print json.dumps(error_details, indent=4) + sys.exit(1) + + +def main(): + spec_json = load_spec_json(); + assert_valid_spec_json(spec_json) + print "Spec JSON is valid." + + +if __name__ == '__main__': + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/remote-playback/README.md b/third_party/WebKit/LayoutTests/external/wpt/remote-playback/README.md index de0a6d8..b934227 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/remote-playback/README.md +++ b/third_party/WebKit/LayoutTests/external/wpt/remote-playback/README.md
@@ -12,8 +12,3 @@ Some behavior would require a real devices to be implemented. In order to keep these tests automated, only behaviors that can be run without user gesture or specific configurations are available here. - -## TODO - -Some tests are missing, including, but not only: -* IDL tests
diff --git a/third_party/WebKit/LayoutTests/external/wpt/scroll-into-view/check-scroll-position.html b/third_party/WebKit/LayoutTests/external/wpt/scroll-into-view/check-scroll-position.html deleted file mode 100644 index 200491a..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/scroll-into-view/check-scroll-position.html +++ /dev/null
@@ -1,77 +0,0 @@ -<!DOCTYPE HTML> -<script src='/resources/testharness.js'></script> -<script src='/resources/testharnessreport.js'></script> -<title> Check End Position of ScrollIntoView</title> -<div id='container' style='height: 2500px; width: 2500px;'> - <div id='content' style='height: 500px; width: 500px;margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;margin-bottom: 1000px'> - </div> -</div> -<script> - -var frames = 0; -var content_height = 500; -var content_width = 500; -var window_height = document.documentElement.clientHeight; -var window_width = document.documentElement.clientWidth; -var content = document.getElementById('content'); - -function animate (funct, x, y, next) { - if (frames < 500) { - ++frames; - requestAnimationFrame(animate.bind(null, funct, x, y, next)); - } else { - funct.step(function() { - assert_approx_equals(window.scrollX, x, 1); - assert_approx_equals(window.scrollY, y, 1); - funct.done(); - if (next) - next(); - }); - } -} - -var checkNearest = async_test("Smooth ScrollIntoView should scroll the element to the 'nearest' position"); -checkNearest.step(function() { - content.scrollIntoView( - {behavior: 'smooth', block: 'nearest', inlinePosition: 'nearest'}); - frames = 0; - var x = content.offsetLeft + content_width - window_width; - var y = content.offsetTop + content_height - window_height; - animate(checkNearest, x, y, test2); -}); - -var checkStart = async_test("Smooth ScrollIntoView should scroll the element to the 'start' position"); -function test2() { - checkStart.step(function() { - content.scrollIntoView( - {behavior: 'smooth', block: 'start', inlinePosition: 'start'}); - frames = 0; - animate(checkStart, content.offsetLeft, content.offsetTop, test3); - }); -} - -var checkCenter = async_test("Smooth ScrollIntoView should scroll the element to the 'center' position"); -function test3() { - checkCenter.step(function() { - content.scrollIntoView( - {behavior: 'smooth', block: 'center', inlinePosition: 'center'}); - frames = 0; - var x = content.offsetLeft + (content_width - window_width) / 2; - var y = content.offsetTop + (content_height - window_height) / 2; - animate(checkCenter, x, y, test4); - }); -} - -var checkEnd = async_test("Smooth ScrollIntoView should scroll the element to the 'end' position"); -function test4() { - checkEnd.step(function() { - content.scrollIntoView( - {behavior: 'smooth', block: 'end', inlinePosition: 'end'}); - frames = 0; - var x = content.offsetLeft + content_width - window_width; - var y = content.offsetTop + content_height - window_height; - animate(checkEnd, x, y, null); - }); -} - -</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/tools/blink-import.py b/third_party/WebKit/LayoutTests/external/wpt/service-workers/tools/blink-import.py new file mode 100644 index 0000000..355df07 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/tools/blink-import.py
@@ -0,0 +1,204 @@ +import os +import re +import shutil +import glob +import tempfile +import sys +from collections import defaultdict + +here = os.path.abspath(os.path.split(__file__)[0]) + +def get_extra_files(chromium_root): + return [(os.path.join(chromium_root, "LayoutTests", "http", "tests", "resources", "testharness-helpers.js"), + os.path.join("resources", "testharness-helpers.js"))] + +resources_re = re.compile("/?(?:\.\./)*resources/(testharness(?:report)?)\.js") + +def resources_path(line, depth): + return False, resources_re.sub(r"/resources/\1.js", line) + +php_re = re.compile("\.php") + +def python_to_php(line, depth): + return False, php_re.sub(".py", line) + +abs_testharness_helpers_re = re.compile("([\"'])/resources/testharness-helpers.js") +testharness_helpers_re = re.compile("\.\./((?:\.\./)*)resources/testharness-helpers.js") + +def testharness_helpers(line, depth): + if abs_testharness_helpers_re.findall(line): + return False, abs_testharness_helpers_re.sub(r"\1%sresources/testharness-helpers.js" % ("../" * (depth - 1)), line) + return False, testharness_helpers_re.sub(r"\1resources/testharness-helpers.js", line) + +serviceworker_path_re = re.compile("/serviceworker/") +def service_worker_path(line, depth): + return False, serviceworker_path_re.sub("/service-workers/", line) + +localhost_re = re.compile("localhost") +alt_host_re = re.compile("127\.0\.0\.1") +port_http_re = re.compile("8000") +port_https_re = re.compile("8000") + + +def server_names(line, depth): + line, count_0 = localhost_re.subn("{{host}}", line) + line, count_1 = alt_host_re.subn("{{domains[www]}}", line) + line, count_2 = port_http_re.subn("{{ports[http][0]}}", line) + line, count_3 = port_https_re.subn("{{ports[https][0]}}", line) + + count = count_0 + count_1 + count_2 + count_3 + + return bool(count), line + + +def source_paths(chromium_root): + for dirpath, dirnames, filenames in os.walk(chromium_root): + if "chromium" in dirnames: + dirnames.remove("chromium") + for filename in filenames: + if filename.endswith("-expected.txt") or filename.endswith(".php"): + continue + yield os.path.relpath(os.path.join(dirpath, filename), chromium_root) + + +def do_subs(path, line): + depth = len(os.path.split(os.path.sep)) + subs = [resources_path, python_to_php, testharness_helpers, service_worker_path, server_names] + file_is_template = False + for sub in subs: + added_template, line = sub(line, depth) + if added_template: + file_is_template = True + return file_is_template, line + +def get_head(git): + return git("rev-parse", "HEAD") + +def get_changes(git, path, old, new): + data = git("diff", "--name-status", "-z", "--no-renames", "%s..%s" % (old, new), "--", path) + items = data.split("\0") + rv = defaultdict(list) + for status, path in items: + rv[status].append(path) + + return rv + +def copy(src_path, out_dir, rel_path): + dest = os.path.normpath(os.path.join(out_dir, rel_path)) + dest_dir = os.path.split(dest)[0] + if not os.path.exists(dest_dir): + os.makedirs(dest_dir) + shutil.copy2(src_path, dest) + +def copy_local_files(local_files, out_root, tmp_dir): + for path in local_files: + rel_path = os.path.relpath(path, out_root) + copy(path, tmp_dir, rel_path) + +def copy_extra_files(chromium_root, tmp_dir): + for in_path, rel_path in get_extra_files(chromium_root): + copy(in_path, tmp_dir, rel_path) + +def sub_changed_filenames(filename_changes, f): + rv = [] + for line in f: + for in_name, out_name in filename_changes.iteritems(): + line = line.replace(in_name, out_name) + rv.append(line) + return "".join(rv) + +testharness_re = re.compile("<script[^>]*src=[\"']?/resources/testharness.js[\"' ][^>]*>") + +def is_top_level_test(path, data): + if os.path.splitext(path)[1] != ".html": + return False + for line in data: + if testharness_re.findall(line): + return True + return False + +def add_suffix(path, suffix): + root, ext = os.path.splitext(path) + return root + ".%s" % suffix + ext + +def main(): + if "--cache-tests" in sys.argv: + sw_path = os.path.join("LayoutTests", "http", "tests", "cachestorage") + out_root = os.path.abspath(os.path.join(here, "..", "cache-storage")) + elif "--sw-tests" in sys.argv: + sw_path = os.path.join("LayoutTests", "http", "tests", "serviceworkers") + out_root = os.path.abspath(os.path.join(here, "..", "service-worker")) + else: + raise ValueError("Must supply either --cache-tests or --sw-tests") + + chromium_root = os.path.abspath(sys.argv[1]) + + work_path = tempfile.mkdtemp() + + test_path = os.path.join(chromium_root, sw_path) + + local_files = glob.glob(os.path.normpath(os.path.join(here, "..", "resources", "*.py"))) + + if not os.path.exists(out_root): + os.mkdir(out_root) + + copy_local_files(local_files, out_root, work_path) + copy_extra_files(chromium_root, work_path) + + path_changes = {} + + for path in source_paths(test_path): + out_path = os.path.join(work_path, path) + out_dir = os.path.dirname(out_path) + if not os.path.exists(out_dir): + os.makedirs(out_dir) + with open(os.path.join(test_path, path), "r") as in_f: + data = [] + sub = False + for line in in_f: + sub_flag, output_line = do_subs(path, line) + data.append(output_line) + if sub_flag: + sub = True + is_test = is_top_level_test(out_path, data) + + initial_path = out_path + + if is_test: + path_1 = add_suffix(out_path, "https") + else: + path_1 = out_path + + if sub: + path_2 = add_suffix(out_path, "sub") + else: + path_2 = path_1 + + if path_2 != initial_path: + path_changes[initial_path] = path_2 + + with open(path_2, "w") as out_f: + out_f.write("".join(data)) + + filename_changes = {} + + for k, v in path_changes.iteritems(): + if os.path.basename(k) in filename_changes: + print "Got duplicate name:" + os.path.basename(k) + filename_changes[os.path.basename(k)] = os.path.basename(v) + + for path in source_paths(work_path): + full_path = os.path.join(work_path, path) + with open(full_path, "r") as f: + data = sub_changed_filenames(filename_changes, f) + with open(full_path, "w") as f: + f.write(data) + + for dirpath, dirnames, filenames in os.walk(work_path): + for filename in filenames: + in_path = os.path.join(dirpath, filename) + rel_path = os.path.relpath(in_path, work_path) + copy(in_path, out_root, rel_path) + +if __name__ == "__main__": + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/generate_javascript.py b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/generate_javascript.py new file mode 100644 index 0000000..184a3945 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/generate_javascript.py
@@ -0,0 +1,52 @@ +from os import path, listdir +from hashlib import sha512, sha256, md5 +from base64 import b64encode +import re + +JS_DIR = path.normpath(path.join(__file__, "..", "..")) + +''' +Yield each file in the javascript directory +''' +def js_files(): + for f in listdir(JS_DIR): + if path.isfile(f) and f.endswith(".js"): + yield f + +''' +URL-safe base64 encode a binary digest and strip any padding. +''' +def format_digest(digest): + return b64encode(digest) + +''' +Generate an encoded sha512 URI. +''' +def sha512_uri(content): + return "sha512-%s" % format_digest(sha512(content).digest()) + +''' +Generate an encoded sha256 URI. +''' +def sha256_uri(content): + return "sha256-%s" % format_digest(sha256(content).digest()) + +''' +Generate an encoded md5 digest URI. +''' +def md5_uri(content): + return "md5-%s" % format_digest(md5(content).digest()) + +def main(): + for file in js_files(): + print "Generating content for %s" % file + base = path.splitext(path.basename(file))[0] + var_name = re.sub(r"[^a-z0-9]", "_", base) + content = "%s=true;" % var_name + with open(file, "w") as f: f.write(content) + print "\tSHA512 integrity: %s" % sha512_uri(content) + print "\tSHA256 integrity: %s" % sha256_uri(content) + print "\tMD5 integrity: %s" % md5_uri(content) + +if __name__ == "__main__": + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/list_hashes.py b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/list_hashes.py new file mode 100644 index 0000000..5e3830a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/subresource-integrity/tools/list_hashes.py
@@ -0,0 +1,57 @@ +from os import path, listdir +from hashlib import sha512, sha384, sha256, md5 +from base64 import b64encode +import re + +DIR = path.normpath(path.join(__file__, "..", "..")) + +''' +Yield each javascript and css file in the directory +''' +def js_and_css_files(): + for f in listdir(DIR): + if path.isfile(f) and (f.endswith(".js") or f.endswith(".css")): + yield f + +''' +URL-safe base64 encode a binary digest and strip any padding. +''' +def format_digest(digest): + return b64encode(digest) + +''' +Generate an encoded sha512 URI. +''' +def sha512_uri(content): + return "sha512-%s" % format_digest(sha512(content).digest()) + +''' +Generate an encoded sha384 URI. +''' +def sha384_uri(content): + return "sha384-%s" % format_digest(sha384(content).digest()) + +''' +Generate an encoded sha256 URI. +''' +def sha256_uri(content): + return "sha256-%s" % format_digest(sha256(content).digest()) + +''' +Generate an encoded md5 digest URI. +''' +def md5_uri(content): + return "md5-%s" % format_digest(md5(content).digest()) + +def main(): + for file in js_and_css_files(): + print "Listing hash values for %s" % file + with open(file, "r") as content_file: + content = content_file.read() + print "\tSHA512 integrity: %s" % sha512_uri(content) + print "\tSHA384 integrity: %s" % sha384_uri(content) + print "\tSHA256 integrity: %s" % sha256_uri(content) + print "\tMD5 integrity: %s" % md5_uri(content) + +if __name__ == "__main__": + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json b/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json index 3682913..9323ba5c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json +++ b/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json
@@ -4973,6 +4973,17 @@ "search": "", "hash": "" }, + "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)", + { + "input": "https://0x100000000/test", + "base": "about:blank", + "failure": true + }, + { + "input": "https://256.0.0.1/test", + "base": "about:blank", + "failure": true + }, "# file URLs containing percent-encoded Windows drive letters (shouldn't work)", { "input": "file:///C%3A/",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/build.py b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/build.py new file mode 100644 index 0000000..d4c0fdf7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/build.py
@@ -0,0 +1,120 @@ +import os +import glob +import shutil +from os import path + + +TEST_FILE_PATTERN = "support/**.test" +TEST_OUTPUT_PATH = "tests" + +TEMPLATE = """\ +<!doctype html> +<!-- DO NOT EDIT! This file and %vtt_file_rel_path are generated. --> +<!-- See /webvtt/parsing/file-parsing/README.md --> +<meta charset=utf-8> +<title>WebVTT parser test: %test_name</title> +%test_headers +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +var t = async_test('%test_name'); +t.step(function(){ + var video = document.createElement('video'); + var track = document.createElement('track'); + assert_true('src' in track, 'track element not supported'); + track.src = '%vtt_file_rel_path'; + track['default'] = true; + track.kind = 'subtitles'; + track.onload = this.step_func(trackLoaded); + track.onerror = this.step_func(trackError); + video.appendChild(track); + document.body.appendChild(video); +}); + +function trackLoaded(event) { + var track = event.target; + var video = track.parentNode; + var cues = video.textTracks[0].cues; + { +%test_js + } + this.done(); +} + +function trackError(e) { + assert_unreached('got unexpected error event'); +} +</script> +""" + +def generate_test(test_path, output_dir): + # Read test file + test_filename = path.basename(test_path) + test_basefilename = path.splitext(test_filename)[0] + + with open(test_path, 'r') as test: + test_source = test.read() + + # Split test header + splits = test_source.split('\n\n', 1) + if len(splits) != 2: + raise ValueError("Leave an empty line between the test header and body") + + test_header, test_body = splits + + # Split header into name + html headers + splits = test_header.split('\n', 1) + + test_name = splits[0] + if len(splits) == 2: + test_headers = splits[1] + + # Split body into js + vtt + splits = test_body.split('\n===\n', 1) + if len(splits) != 2: + raise ValueError("Use === to separate the js and vtt parts") + + test_js, test_vtt = splits + + # Get output paths + os.makedirs(output_dir, exist_ok=True) + html_file_path = path.join(output_dir, test_basefilename + '.html') + + vtt_file_dir = path.join(output_dir, 'support') + os.makedirs(vtt_file_dir, exist_ok=True) + + vtt_file_name = test_basefilename + '.vtt' + vtt_file_path = path.join(vtt_file_dir, vtt_file_name) + vtt_file_rel_path = path.join('support', vtt_file_name) + + # Write html file + with open(html_file_path, 'w') as output: + html = (TEMPLATE.replace('%test_name', test_name) + .replace('%test_headers', test_headers) + .replace('%test_js', test_js) + .replace('%vtt_file_rel_path', vtt_file_rel_path)) + output.write(html) + + # Write vtt file + with open(vtt_file_path, 'w') as output: + encoded = bytes(test_vtt, "utf-8").decode("unicode_escape") + output.write(encoded) + +def main(): + file_parsing_path = path.normpath(path.join(path.dirname(__file__), "..")) + + test_output_path = path.join(file_parsing_path, TEST_OUTPUT_PATH) + + tests_pattern = path.join(file_parsing_path, TEST_FILE_PATTERN) + + # Clean test directory + shutil.rmtree(test_output_path) + + # Generate tests + for file in glob.glob(tests_pattern): + print('Building test files for: ' + file) + generate_test(file, test_output_path) + +if __name__ == '__main__': + main()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/parser.py b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/parser.py new file mode 100644 index 0000000..b77e83de --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/parser.py
@@ -0,0 +1,710 @@ +""" +A direct translation of the webvtt file parsing algorithm. + +See https://w3c.github.io/webvtt/#file-parsing for documentation +""" +import re +import string + +SPACE_CHARACTERS = [' ', '\t', '\n', '\f', '\r'] +SPACE_SPLIT_PATTERN = r"[{}]*".format(''.join(SPACE_CHARACTERS)) +DIGITS = string.digits + +class DictInit: + def __init__(self, **dict): + self.__dict__.update(dict) + +class VTTCue(DictInit): pass +class VTTRegion(DictInit): pass +class Stylesheet(DictInit): pass + +class W3CParser: + input = None + position = None + + def collect_characters(self, condition): + result = "" + while self.position < len(self.input) and condition(self.input[self.position]): + result += self.input[self.position] + self.position += 1 + return result + + def skip_whitespace(self): + self.collect_characters(lambda c: c in SPACE_CHARACTERS) + + def parse_percentage_string(self, input): + 'parse a percentage string' + + # 1. + input = input + + # 2. + if not re.match(r'^\d+(\.\d+)?%$', input): + return None + + # 3. + percentage = float(input[:-1]) + + # 4. + if percentage < 0 or percentage > 100: + return None + + # 5. + return percentage + +class VTTParser(W3CParser): + def __init__(self, input): + self.input = input + self.position = 0 + self.seen_cue = False + + self.text_tracks = [] + self.stylesheets = [] + self.regions = [] + self.errors = [] + + def parse(self): + 'WebVTT parser algorithm' + + # 1. + self.input = self.input.replace('\0', '\ufffd').replace('\r\n', '\n').replace('\r', '\n') + + # 2. + self.position = 0 + + # 3. + self.seen_cue = False + + # 4. + if len(self.input) < 6: + self.errors.append('input too small for webvtt') + return + + # 5. + if len(self.input) == 6 and self.input != 'WEBVTT': + self.errors.append('invalid webvtt header') + return + + # 6. + if len(self.input) > 6: + if not (self.input[0:6] == 'WEBVTT' and self.input[6] in ['\u0020', '\u0009', '\u000A']): + self.errors.append('invalid webvtt header') + return + + # 7. + self.collect_characters(lambda c: c != '\n') + + # 8. + if self.position >= len(self.input): + return + + # 9. + if self.input[self.position] == '\n': + self.position += 1 + + # 10. + if self.position >= len(self.input): + return + + # 11. + if self.input[self.position] != '\n': + self.collect_block(in_header = True) + else: + self.position += 1 + + # 12. + self.collect_characters(lambda c: c == '\n') + + # 13. + self.regions = [] + + # 14. + while self.position < len(self.input): + # 1. + block = self.collect_block() + + # 2. + if isinstance(block, VTTCue): + self.text_tracks.append(block) + + # 3. + elif isinstance(block, Stylesheet): + self.stylesheets.append(block) + + # 4. + elif isinstance(block, VTTRegion): + self.regions.append(block) + + # 5. + self.collect_characters(lambda c: c == '\n') + + # 15. + return + + def collect_block(self, in_header = False): + 'collect a WebVTT block' + + # 1. (done by class) + + line_count = 0 # 2. + previous_position = self.position # 3. + line = "" # 4. + buffer = "" # 5. + seen_eof = False # 6. + seen_arrow = False # 7. + cue = None # 8. + stylesheet = None # 9. + region = None # 10. + + # 11. + while True: + # 1. + line = self.collect_characters(lambda c: c != '\n') + + # 2. + line_count += 1 + + # 3. + if self.position >= len(self.input): + seen_eof = True + else: + self.position += 1 + + # 4. + if '-->' in line: + # 1. + if not in_header and (line_count == 1 or line_count == 2 and not seen_arrow): + # 1. + seen_arrow = True + + # 2. + previous_position = self.position + + # 3. + cue = VTTCue( + id = buffer, + pause_on_exit = False, + region = None, + writing_direction = 'horizontal', + snap_to_lines = True, + line = 'auto', + line_alignment = 'start alignment', + position = 'auto', + position_alignment = 'auto', + cue_size = 100, + text_alignment = 'center', + text = '', + ) + + # 4. + if not VTTCueParser(self, line, cue).collect_cue_timings_and_settings(): + cue = None + else: + buffer = '' + self.seen_cue = True # DIFFERENCE + + else: + self.errors.append('invalid webvtt cue block') + self.position = previous_position + break + + # 5. + elif line == '': + break + + # 6. + else: + # 1. + if not in_header and line_count == 2: + # 1. + if not self.seen_cue and re.match(r'^STYLE\s*$', buffer): + stylesheet = Stylesheet( + location = None, + parent = None, + owner_node = None, + owner_rule = None, + media = None, + title = None, + alternate = False, + origin_clean = True, + source = None, + ) + buffer = '' + # 2. + elif not self.seen_cue and re.match(r'^REGION\s*$', buffer): + region = VTTRegion( + id = '', + width = 100, + lines = 3, + anchor_point = (0, 100), + viewport_anchor_point = (0, 100), + scroll_value = None, + ) + buffer = '' + + # 2. + if buffer != '': + buffer += '\n' + + # 3. + buffer += line + + # 4. + previous_position = self.position + + # 7. + if seen_eof: + break + + # 12. + if cue is not None: + cue.text = buffer + return cue + + # 13. + elif stylesheet is not None: + stylesheet.source = buffer + return stylesheet + + # 14. + elif region is not None: + self.collect_region_settings(region, buffer) + return region + + # 15. + return None + + def collect_region_settings(self, region, input): + 'collect WebVTT region settings' + + # 1. + settings = re.split(SPACE_SPLIT_PATTERN, input) + + # 2. + for setting in settings: + # 1. + if ':' not in setting: + continue + + index = setting.index(':') + if index in [0, len(setting) - 1]: + continue + + # 2. + name = setting[:index] + + # 3. + value = setting[index + 1:] + + # 4. + if name == "id": + region.id = value + + elif name == "width": + percentage = self.parse_percentage_string(value) + if percentage is not None: + region.width = percentage + + elif name == "lines": + # 1. + if not re.match(r'^\d+$', value): + continue + + # 2. + number = int(value) + + # 3. + region.lines = number + + elif name == "regionanchor": + # 1. + if ',' not in value: + continue + + #. 2. + index = value.index(',') + anchorX = value[:index] + + # 3. + anchorY = value[index + 1:] + + # 4. + percentageX = self.parse_percentage_string(anchorX) + percentageY = self.parse_percentage_string(anchorY) + if None in [percentageX, percentageY]: + continue + + # 5. + region.anchor_point = (percentageX, percentageY) + + elif name == "viewportanchor": + # 1. + if ',' not in value: + continue + + #. 2. + index = value.index(',') + viewportanchorX = value[:index] + + # 3. + viewportanchorY = value[index + 1:] + + # 4. + percentageX = self.parse_percentage_string(viewportanchorX) + percentageY = self.parse_percentage_string(viewportanchorY) + if None in [percentageX, percentageY]: + continue + + # 5. + region.viewport_anchor_point = (percentageX, percentageY) + + elif name == "scroll": + # 1. + if value == "up": + region.scroll_value = "up" + + # 5. + continue + + +class VTTCueParser(W3CParser): + def __init__(self, parent, input, cue): + self.parent = parent + self.errors = self.parent.errors + self.input = input + self.position = 0 + self.cue = cue + + def collect_cue_timings_and_settings(self): + 'collect WebVTT cue timings and settings' + + # 1. (handled by class) + + # 2. + self.position = 0 + + # 3. + self.skip_whitespace() + + # 4. + timestamp = self.collect_timestamp() + if timestamp is None: + self.errors.append('invalid start time for VTTCue') + return False + self.cue.start_time = timestamp + + # 5. + self.skip_whitespace() + + # 6. + if self.input[self.position] != '-': + return False + self.position += 1 + + # 7. + if self.input[self.position] != '-': + return False + self.position += 1 + + # 8. + if self.input[self.position] != '>': + return False + self.position += 1 + + # 9. + self.skip_whitespace() + + # 10. + timestamp = self.collect_timestamp() + if timestamp is None: + self.errors.append('invalid end time for VTTCue') + return False + self.cue.end_time = timestamp + + # 11. + remainder = self.input[self.position:] + + # 12. + self.parse_settings(remainder) + + # Extra + return True + + def parse_settings(self, input): + 'parse the WebVTT cue settings' + + # 1. + + settings = re.split(SPACE_SPLIT_PATTERN, input) + + # 2. + for setting in settings: + # 1. + if ':' not in setting: + continue + + index = setting.index(':') + if index in [0, len(setting) - 1]: + continue + + # 2. + name = setting[:index] + + # 3. + value = setting[index + 1:] + + # 4. + if name == 'region': + # 1. + last_regions = (region for region in reversed(self.parent.regions) if region.id == value) + self.cue.region = next(last_regions, None) + + elif name == 'vertical': + # 1. and 2. + if value in ['rl', 'lr']: + self.cue.writing_direction = value + + elif name == 'line': + # 1. + if ',' in value: + index = value.index(',') + linepos = value[:index] + linealign = value[index + 1:] + + # 2. + else: + linepos = value + linealign = None + + # 3. + if not re.search(r'\d', linepos): + continue + + # 4. + if linepos[-1] == '%': + number = self.parse_percentage_string(linepos) + if number is None: + continue + else: + # 1. + if not re.match(r'^[-\.\d]*$', linepos): + continue + + # 2. + if '-' in linepos[1:]: + continue + + # 3. + if linepos.count('.') > 1: + continue + + # 4. + if '.' in linepos: + if not re.search(r'\d\.\d', linepos): + continue + + # 5. + number = float(linepos) + + # 5. + if linealign == "start": + self.cue.line_alignment = 'start' + + # 6. + elif linealign == "center": + self.cue.line_alignment = 'center' + + # 7. + elif linealign == "end": + self.cue.line_alignment = 'end' + + # 8. + elif linealign != None: + continue + + # 9. + self.cue.line = number + + # 10. + if linepos[-1] == '%': + self.cue.snap_to_lines = False + else: + self.cue.snap_to_lines = True + + elif name == 'position': + # 1. + if ',' in value: + index = value.index(',') + colpos = value[:index] + colalign = value[index + 1:] + + # 2. + else: + colpos = value + colalign = None + + # 3. + number = self.parse_percentage_string(colpos) + if number is None: + continue + + # 4. + if colalign == "line-left": + self.cue.line_alignment = 'line-left' + + # 5. + elif colalign == "center": + self.cue.line_alignment = 'center' + + # 6. + elif colalign == "line-right": + self.cue.line_alignment = 'line-right' + + # 7. + elif colalign != None: + continue + + # 8. + self.cue.position = number + + elif name == 'size': + # 1. + number = self.parse_percentage_string(value) + if number is None: + continue + + # 2. + self.cue.cue_size = number + + elif name == 'align': + # 1. + if value == 'start': + self.cue.text_alignment = 'start' + + # 2. + if value == 'center': + self.cue.text_alignment = 'center' + + # 3. + if value == 'end': + self.cue.text_alignment = 'end' + + # 4. + if value == 'left': + self.cue.text_alignment = 'left' + + # 5. + if value == 'right': + self.cue.text_alignment = 'right' + + # 5. + continue + + def collect_timestamp(self): + 'collect a WebVTT timestamp' + + # 1. (handled by class) + + # 2. + most_significant_units = 'minutes' + + # 3. + if self.position >= len(self.input): + return None + + # 4. + if self.input[self.position] not in DIGITS: + return None + + # 5. + string = self.collect_characters(lambda c: c in DIGITS) + + # 6. + value_1 = int(string) + + # 7. + if len(string) != 2 or value_1 > 59: + most_significant_units = 'hours' + + # 8. + if self.position >= len(self.input) or self.input[self.position] != ':': + return None + self.position += 1 + + # 9. + string = self.collect_characters(lambda c: c in DIGITS) + + # 10. + if len(string) != 2: + return None + + # 11. + value_2 = int(string) + + # 12. + if most_significant_units == 'hours' or self.position < len(self.input) and self.input[self.position] == ':': + # 1. + if self.position >= len(self.input) or self.input[self.position] != ':': + return None + self.position += 1 + + # 2. + string = self.collect_characters(lambda c: c in DIGITS) + + # 3. + if len(string) != 2: + return None + + # 4. + value_3 = int(string) + else: + value_3 = value_2 + value_2 = value_1 + value_1 = 0 + + # 13. + if self.position >= len(self.input) or self.input[self.position] != '.': + return None + self.position += 1 + + # 14. + string = self.collect_characters(lambda c: c in DIGITS) + + # 15. + if len(string) != 3: + return None + + # 16. + value_4 = int(string) + + # 17. + if value_2 >= 59 or value_3 >= 59: + return None + + # 18. + result = value_1 * 60 * 60 + value_2 * 60 + value_3 + value_4 / 1000 + + # 19. + return result + + +def main(argv): + files = [open(path, 'r') for path in argv[1:]] + + try: + for file in files: + parser = VTTParser(file.read()) + parser.parse() + + print("Results: {}".format(file)) + print(" Cues: {}".format(parser.text_tracks)) + print(" StyleSheets: {}".format(parser.stylesheets)) + print(" Regions: {}".format(parser.regions)) + print(" Errors: {}".format(parser.errors)) + finally: + for file in files: + file.close() + +if __name__ == '__main__': + import sys + main(sys.argv);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/spec_report.py b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/spec_report.py new file mode 100644 index 0000000..beb140eb8c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tools/spec_report.py
@@ -0,0 +1,99 @@ +import os +import sys +import glob +import html +import fnmatch +from os import path + +import coverage + +OUTPUT_TEMPLATE = """ +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <title>Spec Coverage</title> + <link rel="stylesheet" href="style.css" type="text/css"> + <style> + .covered { + } + + .missed { + background-color: lightcoral; + } + code { + margin: 0; + padding: 0; + display:block; + white-space:pre-wrap; + } + </style> +</head> +<body> + %head + <div><pre> + %body + </pre></div> +</body> +</html> +""" + +LINE_TEMPLATE = "<code class=\"%class\">%lineno| %source</code>" + +def write_report(data, source_file, output_file): + module_name, executable_lines, excluded_lines, missing_lines, _ = data + missing_lines = set(missing_lines) + + with open(output_file, "w") as output, open(source_file, "r") as source: + lines = source.readlines() + + file_report = [] + padding = len(str(len(lines))) + + for index, line in enumerate(lines): + line = line[0:-1] + lineno = index + 1 + line_number = str(lineno).rjust(padding) + + covered = lineno not in missing_lines + line_class = 'covered' if covered else 'missed' + + formatted_line = (LINE_TEMPLATE.replace('%class', line_class) + .replace('%lineno', line_number) + .replace('%source', html.escape(line))) + file_report.append(formatted_line) + + report_body = ''.join(file_report) + + report_header = '' + + report = (OUTPUT_TEMPLATE.replace('%head', report_header) + .replace('%body', report_body)) + output.write(report) + +def main(argv): + parsing_path = path.normpath(path.join(path.dirname(__file__), "..")) + + files = argv[1:] + if not files: + files = [os.path.join(root, file) for root, _, files in os.walk(parsing_path) + for file in fnmatch.filter(files, '*.vtt')] + + cov = coverage.Coverage() + cov.start() + + for file_path in files: + with open(file_path, "r") as file: + source = file.read() + + import parser + p = parser.VTTParser(source) + p.parse() + + cov.stop() + + data = cov.analysis2(parser.__file__) + write_report(data, parser.__file__, "report.html") + +if __name__ == '__main__': + main(sys.argv)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/tools/categorize_results.py b/third_party/WebKit/LayoutTests/external/wpt/webvtt/tools/categorize_results.py new file mode 100644 index 0000000..6cb18c3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/tools/categorize_results.py
@@ -0,0 +1,137 @@ +import os +import sys +import json +import fnmatch + +TEST_DIR = "/webvtt/" +CATEGORIES_FILE = "../categories.json" + +class Test: + def __init__(self, file, name, status, message): + self.file = file + self.name = name + self.status = status + self.message = message + self.passed = status == 'PASS' + self.categories = [] + + @classmethod + def from_json(cls, json): + file = json["test"] + if not file.startswith(TEST_DIR): + return [] + file = file[len(TEST_DIR):] + + status = json["status"] + message = json["message"] + + tests = [] + + for test in json["subtests"]: + name = test["name"] + if status == 'OK': + test_status = test["status"] + test_message = test["message"] + else: + test_status, test_message = status, message + + tests.append(Test(file, name, test_status, test_message)) + + return tests + +class Category: + def __init__(self, names): + self.names = set(names) + self.tests = {} + + @classmethod + def from_json(cls, json): + return Category(json) + + def add_test(self, name, test): + self.tests[test] = name + + def __contains__(self, name): + return name in self.names + +def parse_results(file): + data = json.load(file) + + results = data["results"] + tests = [] + for result in results: + tests += Test.from_json(result) + + return tests + +def parse_categories(file, tests, categories = None, categories_map = None): + data = json.load(file) + basepath = os.path.dirname(file.name) + + categories = categories or [] + + if categories_map: + categories_map = dict(categories_map) + else: + categories_map = {} + + if ":categories" in data: + for cat_data in data[":categories"]: + category = Category.from_json(cat_data) + + categories.append(category) + for name in category.names: + categories_map[name] = category + + for pattern, category_name in data.items(): + if pattern.startswith(":"): + continue + category = categories_map[category_name] + + file_pattern = os.path.normpath(os.path.join(basepath, pattern)) + for test in tests: + if fnmatch.fnmatch(test.name, file_pattern) or fnmatch.fnmatch(test.file, file_pattern): + category.add_test(category_name, test) + test.categories.append(category) + + if ":subcategories" in data: + for subcat_name in data[":subcategories"]: + path = os.path.join(basepath, subcat_name) + file = open(path, "r") + parse_categories(file, tests, categories, categories_map) + + return categories + +def main(argv): + if len(argv) == 1: + if argv[0] == '-': + results_file = sys.stdin + else: + results_file = open(argv[0], "r") + else: + print("USAGE: python3 categorize_results.py <file>") + print("<file>\tA file containing wpt results. Or `-` for reading results from stdin.") + return + + filepath = os.path.dirname(__file__) + categories_path = os.path.join(filepath, CATEGORIES_FILE) + categories_file = open(categories_path, "r") + + tests = parse_results(results_file) + categories = parse_categories(categories_file, tests) + + for category in categories: + tests_by_name = { name: [] for name in category.names } + for test, name in category.tests.items(): + tests_by_name[name].append(test) + + for name in category.names: + test_group = tests_by_name[name] + amount = len(test_group) + if amount == 0: + continue + passed = sum(1 for test in test_group if test.passed) + print("{}:\t{}/{} - {}%".format(name, passed, amount, round(passed / amount * 100, 2))) + +if __name__ == "__main__": + main(sys.argv[1:])
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values-expected.txt b/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values-expected.txt index 1e0e745..b62bbe7 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values-expected.txt
@@ -3,8 +3,6 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - -Verifying initial values are supported when grid is ENABLED. PASS CSS.supports('align-items', 'normal') is true PASS CSS.supports('align-self', 'auto') is true PASS CSS.supports('align-content', 'normal') is true @@ -21,24 +19,6 @@ PASS CSS.supports('align-self', 'auto') is true PASS CSS.supports('align-content', 'normal') is true PASS CSS.supports('justify-content', 'normal') is true - -Verifying initial values are supported when grid is DISABLED. -PASS CSS.supports('align-items', 'stretch') is true -PASS CSS.supports('align-self', 'auto') is true -PASS CSS.supports('align-content', 'stretch') is true -PASS CSS.supports('justify-content', 'flex-start') is true -PASS CSS.supports('align-items', 'stretch') is true -PASS CSS.supports('align-self', 'auto') is true -PASS CSS.supports('align-content', 'stretch') is true -PASS CSS.supports('justify-content', 'flex-start') is true -PASS CSS.supports('align-items', 'stretch') is true -PASS CSS.supports('align-self', 'auto') is true -PASS CSS.supports('align-content', 'stretch') is true -PASS CSS.supports('justify-content', 'flex-start') is true -PASS CSS.supports('align-items', 'stretch') is true -PASS CSS.supports('align-self', 'auto') is true -PASS CSS.supports('align-content', 'stretch') is true -PASS CSS.supports('justify-content', 'flex-start') is true PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values.html b/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values.html index 335ccbd..7bd850b 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values.html +++ b/third_party/WebKit/LayoutTests/fast/alignment/ensure-flexbox-compatibility-with-initial-values.html
@@ -20,47 +20,35 @@ checkSupportedValues(element.id, "justify-content"); } -function checkInitialValues(gridEnabled) -{ - if (window.internals) - internals.runtimeFlags.cssGridLayoutEnabled = gridEnabled; +var root = document.createElement("div"); +document.body.appendChild(root); - var root = document.createElement("div"); - document.body.appendChild(root); +var container = document.createElement("div"); +container.id = "container"; +root.appendChild(container); +var item = document.createElement("div"); +item.id = "item"; +container.appendChild(item); - var container = document.createElement("div"); - container.id = "container"; - root.appendChild(container); - var item = document.createElement("div"); - item.id = "item"; - container.appendChild(item); +var flexContainer = document.createElement("div"); +flexContainer.id = "flexContainer"; +flexContainer.style.display = "flex"; +root.appendChild(flexContainer); +var flexItem = document.createElement("div"); +flexItem.id = "flexItem"; +flexContainer.appendChild(flexItem); - var flexContainer = document.createElement("div"); - flexContainer.id = "flexContainer"; - flexContainer.style.display = "flex"; - root.appendChild(flexContainer); - var flexItem = document.createElement("div"); - flexItem.id = "flexItem"; - flexContainer.appendChild(flexItem); +setInitialValues(root); +setInitialValues(container); +setInitialValues(item); +setInitialValues(flexContainer); +setInitialValues(flexItem); - setInitialValues(root); - setInitialValues(container); - setInitialValues(item); - setInitialValues(flexContainer); - setInitialValues(flexItem); +checkSupportedInitialValues(container); +checkSupportedInitialValues(item); +checkSupportedInitialValues(flexContainer); +checkSupportedInitialValues(flexItem); - checkSupportedInitialValues(container); - checkSupportedInitialValues(item); - checkSupportedInitialValues(flexContainer); - checkSupportedInitialValues(flexItem); - - document.body.removeChild(root); -} - -debug('<br>Verifying initial values are supported when grid is ENABLED.'); -checkInitialValues(true); - -debug('<br>Verifying initial values are supported when grid is DISABLED.'); -checkInitialValues(false); +document.body.removeChild(root); </script> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values-invalid-if-grid-not-enabled.html b/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values-invalid-if-grid-not-enabled.html deleted file mode 100644 index b767aa9..0000000 --- a/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values-invalid-if-grid-not-enabled.html +++ /dev/null
@@ -1,89 +0,0 @@ -<!DOCTYPE html> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script src="resources/alignment-parsing-utils-th.js"></script> -<html> - <body> - <p>Test to verify that the new alignment values are parsed as invalid if Grid Layout is disabled and in any case they do not cause a crash because assertions in flexbox layout code.</p> - <div id="log"></div> - - <div id="flexContainer" style="display: flex"> - <div id="flexItem"></div> - </div> -<script> - -var container = document.getElementById("flexContainer"); -var item = document.getElementById("flexItem"); - -function checkAlignSelfValue(value, computedValue, gridEnabled) -{ - item.style.webkitAlignSelf = value; - if (gridEnabled) - checkValues(item, "alignSelf", "align-self", value, computedValue); - else - checkValues(item, "alignSelf", "align-self", "flex-start", "flex-start"); -} - -function checkAlignItemsValue(value, computedValue, gridEnabled) -{ - container.style.webkitAlignItems = value; - if (gridEnabled) { - checkValues(container, "alignItems", "align-items", value, computedValue); - checkValues(item, "alignSelf", "align-self", "auto", "auto"); - } else { - checkValues(container, "alignItems", "align-items", "flex-end", "flex-end"); - checkValues(item, "alignSelf", "align-self", "auto", "auto"); - } -} - -function checkSelfAlignmentValues(gridEnabled) -{ - if (window.internals) - internals.runtimeFlags.cssGridLayoutEnabled = gridEnabled; - - item.style.webkitAlignSelf = "flex-start"; - - checkAlignSelfValue("start unsafe", "start unsafe", gridEnabled) - checkAlignSelfValue("start", "start", gridEnabled) - checkAlignSelfValue("end", "end", gridEnabled) - checkAlignSelfValue("flex-start safe", "flex-start safe", gridEnabled) - checkAlignSelfValue("self-start", "self-start", gridEnabled) - checkAlignSelfValue("self-end", "self-end", gridEnabled) -} - -function checkDefaultAlignmentValues(gridEnabled) -{ - if (window.internals) - internals.runtimeFlags.cssGridLayoutEnabled = gridEnabled; - - container.style.webkitAlignItems = "flex-end"; - item.style.webkitAlignSelf = "auto"; - - checkAlignItemsValue("start unsafe", "start unsafe", gridEnabled) - checkAlignItemsValue("start", "start", gridEnabled) - checkAlignItemsValue("end", "end", gridEnabled) - checkAlignItemsValue("flex-start safe", "flex-start safe", gridEnabled) - checkAlignItemsValue("self-start", "self-start", gridEnabled) - checkAlignItemsValue("self-end", "self-end", gridEnabled) -} - -test(function() { - checkSelfAlignmentValues(false); -}, "New Self-Alignment values should be invalid when grid layout is DISABLED."); - -test(function() { - checkDefaultAlignmentValues(false); -}, "New Default-Alignment values should be invalid when grid layout is DISABLED."); - -test(function() { - checkSelfAlignmentValues(true); -}, "Even when grid layout is ENABLED, new Self-Alignment values should not violate assertions in FlexibleBox layout logic.."); - -test(function() { - checkDefaultAlignmentValues(true); -}, "Even when grid layout is ENABLED, new Default-Alignment values should not violate assertions in FlexibleBox layout logic.."); - -</script> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values.html b/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values.html new file mode 100644 index 0000000..4dd11c65 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/alignment/new-alignment-values.html
@@ -0,0 +1,67 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/alignment-parsing-utils-th.js"></script> +<html> + <body> + <p>Test to verify that the new alignment values do not hit assertions in flexbox layout code.</p> + <div id="log"></div> + + <div id="flexContainer" style="display: flex"> + <div id="flexItem"></div> + </div> +<script> + +var container = document.getElementById("flexContainer"); +var item = document.getElementById("flexItem"); + +function checkAlignSelfValue(value, computedValue) +{ + item.style.webkitAlignSelf = value; + checkValues(item, "alignSelf", "align-self", value, computedValue); +} + +function checkAlignItemsValue(value, computedValue) +{ + container.style.webkitAlignItems = value; + checkValues(container, "alignItems", "align-items", value, computedValue); + checkValues(item, "alignSelf", "align-self", "auto", "auto"); +} + +function checkSelfAlignmentValues() +{ + item.style.webkitAlignSelf = "flex-start"; + + checkAlignSelfValue("start unsafe", "start unsafe") + checkAlignSelfValue("start", "start") + checkAlignSelfValue("end", "end") + checkAlignSelfValue("flex-start safe", "flex-start safe") + checkAlignSelfValue("self-start", "self-start") + checkAlignSelfValue("self-end", "self-end") +} + +function checkDefaultAlignmentValues() +{ + container.style.webkitAlignItems = "flex-end"; + item.style.webkitAlignSelf = "auto"; + + checkAlignItemsValue("start unsafe", "start unsafe") + checkAlignItemsValue("start", "start") + checkAlignItemsValue("end", "end") + checkAlignItemsValue("flex-start safe", "flex-start safe") + checkAlignItemsValue("self-start", "self-start") + checkAlignItemsValue("self-end", "self-end") +} + +test(function() { + checkSelfAlignmentValues(true); +}, "New Self-Alignment values should not violate assertions in FlexibleBox layout logic.."); + +test(function() { + checkDefaultAlignmentValues(true); +}, "New Default-Alignment values should not violate assertions in FlexibleBox layout logic.."); + +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/css/remove-pending-sheet-html-import-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/css/remove-pending-sheet-html-import-crash-expected.txt index 0b6d0b7..938bab7a 100644 --- a/third_party/WebKit/LayoutTests/fast/css/remove-pending-sheet-html-import-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/css/remove-pending-sheet-html-import-crash-expected.txt
@@ -1 +1,2 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS if this test didn't crash.
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-click-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-click-expected.txt index 5fb2105..7ef72d2ba 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-click-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-click-expected.txt
@@ -1,5 +1,7 @@ PASS autoscroll started +Mouse cursor shape: type=SouthPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-drag-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-drag-expected.txt index 5fb2105..7ef72d2ba 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-drag-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-drag-expected.txt
@@ -1,5 +1,7 @@ PASS autoscroll started +Mouse cursor shape: type=SouthPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-event-fired-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-event-fired-expected.txt index 5fb2105..7ef72d2ba 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-event-fired-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-event-fired-expected.txt
@@ -1,5 +1,7 @@ PASS autoscroll started +Mouse cursor shape: type=SouthPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-in-iframe-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-in-iframe-expected.txt index 5fb2105..7ef72d2ba 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-in-iframe-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-in-iframe-expected.txt
@@ -1,5 +1,7 @@ PASS autoscroll started +Mouse cursor shape: type=SouthPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-expected.txt index 5fb2105..7ef72d2ba 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-expected.txt
@@ -1,5 +1,7 @@ PASS autoscroll started +Mouse cursor shape: type=SouthPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-forbidden-expected.txt b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-forbidden-expected.txt index 77ced747..8607ed0 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-forbidden-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-nested-divs-forbidden-expected.txt
@@ -7,7 +7,9 @@ Test for bug 232965 This tests that vertical pan scrolling does not propagate from the inner div to the outer div when the outer div has no vertical overflow. PASS autoscroll started +Mouse cursor shape: type=NorthEastPanning hotSpot=0,0 PASS autoscroll stopped +PASS Mouse cursor cleared PASS outerdiv.scrollLeft is not 0 PASS outerdiv.scrollTop is 0 PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-use-count.html b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-use-count.html index 8ffbf9f3..3190e71 100644 --- a/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-use-count.html +++ b/third_party/WebKit/LayoutTests/fast/events/middleClickAutoscroll-use-count.html
@@ -31,5 +31,6 @@ eventSender.mouseDown(middleButton); eventSender.mouseMoveTo(endX, endY); assert_true(internals.isUseCounted(document, middleClickAutoscrollStart)); + eventSender.mouseUp(middleButton); }) </script>
diff --git a/third_party/WebKit/LayoutTests/fast/events/resources/middleClickAutoscroll.js b/third_party/WebKit/LayoutTests/fast/events/resources/middleClickAutoscroll.js index 73de8b2f..f1763b8 100644 --- a/third_party/WebKit/LayoutTests/fast/events/resources/middleClickAutoscroll.js +++ b/third_party/WebKit/LayoutTests/fast/events/resources/middleClickAutoscroll.js
@@ -50,6 +50,8 @@ return; scrolled = true; testPassed('autoscroll started'); + var cursorInfo = window.internals.getCurrentCursorInfo(); + debug("Mouse cursor shape: " + cursorInfo); if (window.eventSender) { if (param.clickOrDrag == 'click') @@ -64,6 +66,12 @@ noMoreScroll = true; window.setTimeout(function() { testPassed('autoscroll stopped'); + var cursorInfo = window.internals.getCurrentCursorInfo(); + if (cursorInfo == "type=Pointer hotSpot=0,0" || cursorInfo == "type=IBeam hotSpot=0,0") + testPassed('Mouse cursor cleared'); + else + testFailed('Mouse cursor shape: ' + cursorInfo); + finishTest(); }, autoscrollInterval * 2); };
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-link-with-media-query-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-link-with-media-query-expected.txt index 611b005..120c9c2 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-link-with-media-query-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-link-with-media-query-expected.txt
@@ -1 +1,2 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. This test passes if it does not crash under ASAN.
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-onload-with-stylesheets-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-onload-with-stylesheets-expected.txt index 129ac10f..8e9f01d 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-onload-with-stylesheets-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-onload-with-stylesheets-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS event.target.import.querySelector('link').sheet instanceof StyleSheet is true PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-basic-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-basic-expected.txt index e0d6a42..983c6c5f 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-basic-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-basic-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS document.styleSheets.length is 2 PASS importLink.import.styleSheets.length is 1 PASS window.getComputedStyle(shouldBeBlue).color is "rgb(0, 0, 255)"
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-block-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-block-expected.txt index 44f66de..028079a 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-block-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-block-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS childStyleLink.sheet.title is "Script Blocker" PASS importLink.import is non-null. PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-expected.txt index 326c5630..f691039 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-link-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS childStyleLink.sheet.title is "Script Blocker" PASS window.getComputedStyle(shouldBeBlue).color is "rgb(0, 0, 255)" PASS window.getComputedStyle(shouldBeAqua).color is "rgb(0, 255, 255)"
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-dedup-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-dedup-expected.txt index 26a9fe4..0305a4a7 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-dedup-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-dedup-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS colorOf(target1) is 'rgb(0, 128, 0)' PASS colorOf(target2) is 'rgb(255, 0, 0)' PASS colorOf(target3) is 'rgb(255, 0, 0)'
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-expected.txt index 0e7ba35..830d336 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/import-style-tree-order-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS window.getComputedStyle(styleShouldBeHiddenByImport).color is "rgb(0, 128, 0)" PASS window.getComputedStyle(linkShouldBeHiddenByImport).color is "rgb(0, 128, 0)" PASS window.getComputedStyle(importShouldBeHiddenByImport).color is "rgb(0, 128, 0)"
diff --git a/third_party/WebKit/LayoutTests/fast/html/imports/window-onload-with-import-stylesheet-expected.txt b/third_party/WebKit/LayoutTests/fast/html/imports/window-onload-with-import-stylesheet-expected.txt index 8cf04f5..e8ddcac 100644 --- a/third_party/WebKit/LayoutTests/fast/html/imports/window-onload-with-import-stylesheet-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/html/imports/window-onload-with-import-stylesheet-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. PASS target.import.querySelector('link').sheet instanceof StyleSheet is true PASS successfullyParsed is true
diff --git a/third_party/WebKit/LayoutTests/http/tests/htmlimports/import-preload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/htmlimports/import-preload-expected.txt index 380c051..627f279 100644 --- a/third_party/WebKit/LayoutTests/http/tests/htmlimports/import-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/htmlimports/import-preload-expected.txt
@@ -1,2 +1,3 @@ CONSOLE MESSAGE: line 9: PASS: resources/preload.html is preloaded. +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt index 39e1870..72f1636 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/html-link-import-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. This test verifies that imported document is rendered within the import link. - <html>
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt b/third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt index 63d4f00..83e111e 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-rule-from-imported-stylesheet-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: Styling master document from stylesheets defined in HTML Imports is deprecated, and is planned to be removed in M65, around March 2018. Please refer to https://goo.gl/EGXzpw for possible migration paths. Tests that rules from imported stylesheets are correctly shown and are editable in inspector. Rules before toggling:
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt index 631a49d..20e2eb92 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt index 631a49d..20e2eb92 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt index cac2f08..cc06173 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 231 tests; 92 PASS, 139 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 241 tests; 98 PASS, 143 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw @@ -181,6 +181,16 @@ PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://0x100000000/test should throw +PASS sendBeacon(): https://0x100000000/test should throw +FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://0x100000000/test should throw +FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://256.0.0.1/test should throw +PASS sendBeacon(): https://256.0.0.1/test should throw +FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://256.0.0.1/test should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt index 0fe3a1e9..bbafd42 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 479 tests; 368 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 481 tests; 370 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS URL.searchParams getter PASS URL.searchParams updating, clearing PASS URL.searchParams setter, invalid values @@ -438,6 +438,8 @@ PASS Parsing: <http://256.256.256.256> against <http://other.com/> PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt index 631a49d..20e2eb92 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt index 631a49d..20e2eb92 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt index cac2f08..cc06173 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 231 tests; 92 PASS, 139 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 241 tests; 98 PASS, 143 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw @@ -181,6 +181,16 @@ PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://0x100000000/test should throw +PASS sendBeacon(): https://0x100000000/test should throw +FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://0x100000000/test should throw +FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://256.0.0.1/test should throw +PASS sendBeacon(): https://256.0.0.1/test should throw +FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://256.0.0.1/test should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt index 0fe3a1e9..bbafd42 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 479 tests; 368 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 481 tests; 370 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS URL.searchParams getter PASS URL.searchParams updating, clearing PASS URL.searchParams setter, invalid values @@ -438,6 +438,8 @@ PASS Parsing: <http://256.256.256.256> against <http://other.com/> PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt index c2ed542..342c6e5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt index c2ed542..342c6e5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 475 tests; 304 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 477 tests; 306 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS Parsing: <http://example . org> against <http://example.org/foo/bar> @@ -394,6 +394,8 @@ FAIL Parsing: <http://256.256.256.256> against <http://other.com/> assert_equals: failure should set href to input expected "http://256.256.256.256" but got "http://256.256.256.256/" PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt index 8c5ca0477..6afafd6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 231 tests; 93 PASS, 138 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 241 tests; 99 PASS, 142 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw @@ -181,6 +181,16 @@ PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://0x100000000/test should throw +PASS sendBeacon(): https://0x100000000/test should throw +FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://0x100000000/test should throw +FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw +PASS XHR: https://256.0.0.1/test should throw +PASS sendBeacon(): https://256.0.0.1/test should throw +FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") +PASS window.open(): https://256.0.0.1/test should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt index 97c9bc6..aa272e1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 479 tests; 368 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 481 tests; 370 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS URL.searchParams getter PASS URL.searchParams updating, clearing PASS URL.searchParams setter, invalid values @@ -438,6 +438,8 @@ PASS Parsing: <http://256.256.256.256> against <http://other.com/> PASS Parsing: <http://256.256.256.256.256> against <http://other.com/> PASS Parsing: <https://0x.0x.0> against <about:blank> +PASS Parsing: <https://0x100000000/test> against <about:blank> +PASS Parsing: <https://256.0.0.1/test> against <about:blank> PASS Parsing: <file:///C%3A/> against <about:blank> PASS Parsing: <file:///C%7C/> against <about:blank> PASS Parsing: <pix/submit.gif> against <file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html>
diff --git a/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js b/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js index 2846e8d..066ba62 100644 --- a/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js +++ b/third_party/WebKit/LayoutTests/vr/resources/mock-vr-service.js
@@ -13,7 +13,7 @@ this.displayClient_ = new vr_service.VRDisplayClientPtr(); this.displayInfo_ = displayInfo; this.service_ = service; - this.vsync_provider_ = new MockVRVSyncProvider(); + this.presentation_provider_ = new MockVRPresentationProvider(); interfaceProvider.addInterfaceOverrideForTesting( vr_service.VRDisplay.name, @@ -24,37 +24,24 @@ } } - requestPresent(secureOrigin, submitFrameClient) { - this.submitFrameClient_ = submitFrameClient; + requestPresent(secureOrigin, submitFrameClient, request) { + this.presentation_provider_.bind(submitFrameClient, request); return Promise.resolve({success: true}); } - submitFrame(frameId, mailboxHolder) { - // Trigger the submit completion callbacks here. WARNING: The - // Javascript-based mojo mocks are *not* re-entrant. In the current - // default implementation, Javascript calls display.submitFrame, and the - // corresponding C++ code uses a reentrant mojo call that waits for - // onSubmitFrameTransferred to indicate completion. This never finishes - // when using the mocks since the incoming calls are queued until the - // current execution context finishes. As a workaround, use the alternate - // "WebVRExperimentalRendering" mode which works without reentrant calls, - // the code only checks for completion on the *next* frame, see the - // corresponding option setting in RuntimeEnabledFeatures.json5. - this.submitFrameClient_.onSubmitFrameTransferred(); - this.submitFrameClient_.onSubmitFrameRendered(); - } - setPose(pose) { if (pose == null) { - this.vsync_provider_.pose_ = null; + this.presentation_provider_.pose_ = null; } else { - this.vsync_provider_.initPose(); - this.vsync_provider_.fillPose(pose); + this.presentation_provider_.initPose(); + this.presentation_provider_.fillPose(pose); } } - getVRVSyncProvider(request) { - this.vsync_provider_.bind(request); + getNextMagicWindowPose() { + return Promise.resolve({ + pose: this.presentation_provider_.pose_, + }); } forceActivate(reason) { @@ -73,16 +60,32 @@ } } - class MockVRVSyncProvider { + class MockVRPresentationProvider { constructor() { this.timeDelta_ = 0; - this.binding_ = new bindings.Binding(vr_service.VRVSyncProvider, this); + this.binding_ = new bindings.Binding(vr_service.VRPresentationProvider, + this); this.pose_ = null; } - bind(request) { + bind(client, request) { + this.submitFrameClient_ = client; this.binding_.close(); this.binding_.bind(request); } + submitFrame(frameId, mailboxHolder) { + // Trigger the submit completion callbacks here. WARNING: The + // Javascript-based mojo mocks are *not* re-entrant. In the current + // default implementation, Javascript calls display.submitFrame, and the + // corresponding C++ code uses a reentrant mojo call that waits for + // onSubmitFrameTransferred to indicate completion. This never finishes + // when using the mocks since the incoming calls are queued until the + // current execution context finishes. As a workaround, use the alternate + // "WebVRExperimentalRendering" mode which works without reentrant calls, + // the code only checks for completion on the *next* frame, see the + // corresponding option setting in RuntimeEnabledFeatures.json5. + this.submitFrameClient_.onSubmitFrameTransferred(); + this.submitFrameClient_.onSubmitFrameRendered(); + } getVSync() { if (this.pose_) { this.pose_.poseIndex++; @@ -93,8 +96,8 @@ time: { microseconds: this.timeDelta_, }, - frameId: 0, - error: vr_service.VRVSyncProvider.Status.SUCCESS, + frame_id: 0, + status: vr_service.VRPresentationProvider.VSyncStatus.SUCCESS, }); this.timeDelta_ += 1000.0 / 60.0; @@ -157,7 +160,7 @@ } let device_number = this.mockVRDisplays_.length; - return Promise.resolve({numberOfConnectedDevices: device_number}); + return Promise.resolve({number_of_connected_devices: device_number}); } }
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py index 4421b91..6749cd17 100755 --- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py +++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -31,10 +31,11 @@ 'DataRef', 'RefPtr', 'DataPersistent', 'Persistent', 'std::unique_ptr', 'Vector<String>', 'Font', 'FillLayer', 'NinePieceImage', # Aligns like float - 'TransformOrigin', 'LengthBox', 'LengthSize', 'FloatSize', 'LengthPoint', 'Length', - 'TextSizeAdjust', 'TabSize', 'float', + 'TransformOrigin', 'ScrollPadding', 'ScrollSnapMargin', 'LengthBox', 'LengthSize', 'FloatSize', + 'LengthPoint', 'Length', 'TextSizeAdjust', 'TabSize', 'float', # Aligns like int - 'BorderValue', 'StyleColor', 'Color', 'LayoutUnit', 'LineClampValue', 'OutlineValue', 'unsigned', 'int', + 'ScrollSnapType', 'ScrollSnapAlign', 'BorderValue', 'StyleColor', 'Color', 'LayoutUnit', + 'LineClampValue', 'OutlineValue', 'unsigned', 'int', # Aligns like short 'unsigned short', 'short', # Aligns like char
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 0925f7e9..e62e4663 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1475,6 +1475,7 @@ "//testing/gmock", "//testing/gtest", "//third_party/WebKit/Source/core/editing:unit_tests", + "//third_party/WebKit/Source/core/mojo:unit_tests", ] }
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index b830b0a3..9cb415d55 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1994,6 +1994,11 @@ converter: "ConvertSnapType", getter: "GetScrollSnapType", runtime_flag: "CSSScrollSnapPoints", + field_template: "storage_only", + type_name: "ScrollSnapType", + field_group: "rare-non-inherited->scroll-snap", + include_paths: ["core/style/ScrollSnap.h"], + default_value: "ScrollSnapType()", }, { name: "scroll-snap-align", @@ -2002,6 +2007,11 @@ converter: "ConvertSnapAlign", getter: "GetScrollSnapAlign", runtime_flag: "CSSScrollSnapPoints", + field_template: "storage_only", + type_name: "ScrollSnapAlign", + field_group: "rare-non-inherited->scroll-snap", + default_value: "ScrollSnapAlign()", + include_paths: ["core/style/ScrollSnap.h"], }, { name: "scroll-snap-stop",
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 index 8d4ff1d2..8514f2b33 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 +++ b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5
@@ -934,6 +934,22 @@ default_value: "StyleMotionData(LengthPoint(Length(kAuto), Length(kAuto)), LengthPoint(Length(kAuto), Length(kAuto)), nullptr, Length(0, kFixed), StyleOffsetRotation(0, kOffsetRotationAuto))", include_paths: ["core/style/StyleMotionData.h"], }, + { + name: "ScrollPadding", + field_template: "storage_only", + type_name: "ScrollPadding", + field_group: "rare-non-inherited->scroll-snap", + default_value: "Length()", + include_paths: ["core/style/ScrollSnap.h"], + }, + { + name: "ScrollSnapMargin", + field_template: "storage_only", + type_name: "ScrollSnapMargin", + field_group: "rare-non-inherited->scroll-snap", + default_value: "Length()", + include_paths: ["core/style/ScrollSnap.h"], + }, // TODO(shend): These are subgroups and should be removed when we can // generate them propertly. { @@ -945,14 +961,5 @@ wrapper_pointer_name: "DataRef", include_paths: ["core/style/StyleGridData.h"], }, - { - name: "ScrollSnapData", - field_template: "storage_only", - type_name: "StyleScrollSnapData", - field_group: "rare-non-inherited", - default_value: "", - wrapper_pointer_name: "DataRef", - include_paths: ["core/style/StyleScrollSnapData.h"], - }, ], }
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h index eb69d8a9..02b3614 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h +++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -38,7 +38,6 @@ #include "core/style/ShadowList.h" #include "core/style/StyleOffsetRotation.h" #include "core/style/StyleReflection.h" -#include "core/style/StyleScrollSnapData.h" #include "core/style/TransformOrigin.h" #include "platform/LengthSize.h" #include "platform/fonts/FontDescription.h"
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index 2bff5dd1..afd4948 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -467,6 +467,9 @@ options.behavior() == "smooth") { options.setBehavior("instant"); } + } else if (arg.isNull()) { + options.setBlock("start"); + options.setInlinePosition("nearest"); } scrollIntoViewWithOptions(options); }
diff --git a/third_party/WebKit/Source/core/dom/Element.idl b/third_party/WebKit/Source/core/dom/Element.idl index f642b455..c0bbbc9 100644 --- a/third_party/WebKit/Source/core/dom/Element.idl +++ b/third_party/WebKit/Source/core/dom/Element.idl
@@ -95,7 +95,7 @@ ClientRectList getClientRects(); ClientRect getBoundingClientRect(); - void scrollIntoView(optional (ScrollIntoViewOptions or boolean)? arg); + void scrollIntoView(optional (ScrollIntoViewOptions or boolean) arg); [RuntimeEnabled=CSSOMSmoothScroll, ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options); [RuntimeEnabled=CSSOMSmoothScroll, ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y); [RuntimeEnabled=CSSOMSmoothScroll] void scrollTo(optional ScrollToOptions options);
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn index 45b41600..8e0ef90 100644 --- a/third_party/WebKit/Source/core/editing/BUILD.gn +++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -42,6 +42,8 @@ "FrameSelection.h", "GranularityStrategy.cpp", "GranularityStrategy.h", + "InlineBoxTraversal.cpp", + "InlineBoxTraversal.h", "InputMethodController.cpp", "InputMethodController.h", "LayoutSelection.cpp",
diff --git a/third_party/WebKit/Source/core/editing/InlineBoxTraversal.cpp b/third_party/WebKit/Source/core/editing/InlineBoxTraversal.cpp new file mode 100644 index 0000000..f85c063 --- /dev/null +++ b/third_party/WebKit/Source/core/editing/InlineBoxTraversal.cpp
@@ -0,0 +1,117 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/editing/InlineBoxTraversal.h" + +#include "core/layout/line/InlineBox.h" + +namespace blink { + +namespace { + +// "Left" Traversal strategy +struct TraverseLeft { + STATIC_ONLY(TraverseLeft); + + static InlineBox* Forward(const InlineBox& inline_box) { + return inline_box.PrevLeafChild(); + } +}; + +// "Left" Traversal strategy ignoring line break +struct TraverseLeftIgnoringLineBreak { + STATIC_ONLY(TraverseLeftIgnoringLineBreak); + + static InlineBox* Forward(const InlineBox& inline_box) { + return inline_box.PrevLeafChildIgnoringLineBreak(); + } +}; + +// "Right" Traversal strategy +struct TraverseRight { + STATIC_ONLY(TraverseRight); + + static InlineBox* Forward(const InlineBox& inline_box) { + return inline_box.NextLeafChild(); + } +}; + +// "Right" Traversal strategy ignoring line break +struct TraverseRightIgnoringLineBreak { + STATIC_ONLY(TraverseRightIgnoringLineBreak); + + static InlineBox* Forward(const InlineBox& inline_box) { + return inline_box.NextLeafChildIgnoringLineBreak(); + } +}; + +template <typename TraversalStrategy> +InlineBox* FindBoudnaryOfBidiRun(const InlineBox& start, unsigned bidi_level) { + InlineBox* result = const_cast<InlineBox*>(&start); + for (InlineBox* runner = TraversalStrategy::Forward(start); runner; + runner = TraversalStrategy::Forward(*runner)) { + if (runner->BidiLevel() <= bidi_level) + return result; + result = runner; + } + return result; +} + +template <typename TraversalStrategy> +InlineBox* FindBoudnaryOfEntireBidiRun(const InlineBox& start, + unsigned bidi_level) { + InlineBox* result = const_cast<InlineBox*>(&start); + for (InlineBox* runner = TraversalStrategy::Forward(start); runner; + runner = TraversalStrategy::Forward(*runner)) { + if (runner->BidiLevel() < bidi_level) + return result; + result = runner; + } + return result; +} + +} // namespace + +InlineBox* InlineBoxTraversal::FindLeftBoundaryOfBidiRunIgnoringLineBreak( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfBidiRun<TraverseLeftIgnoringLineBreak>(inline_box, + bidi_level); +} + +InlineBox* InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRun( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfEntireBidiRun<TraverseLeft>(inline_box, bidi_level); +} + +InlineBox* InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfEntireBidiRun<TraverseLeftIgnoringLineBreak>(inline_box, + bidi_level); +} + +InlineBox* InlineBoxTraversal::FindRightBoundaryOfBidiRunIgnoringLineBreak( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfBidiRun<TraverseRightIgnoringLineBreak>(inline_box, + bidi_level); +} + +InlineBox* InlineBoxTraversal::FindRightBoundaryOfEntireBidiRun( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfEntireBidiRun<TraverseRight>(inline_box, bidi_level); +} + +InlineBox* +InlineBoxTraversal::FindRightBoundaryOfEntireBidiRunIgnoringLineBreak( + const InlineBox& inline_box, + unsigned bidi_level) { + return FindBoudnaryOfEntireBidiRun<TraverseRightIgnoringLineBreak>( + inline_box, bidi_level); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/InlineBoxTraversal.h b/third_party/WebKit/Source/core/editing/InlineBoxTraversal.h new file mode 100644 index 0000000..e7c1b37 --- /dev/null +++ b/third_party/WebKit/Source/core/editing/InlineBoxTraversal.h
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef InlineBoxTraversal_h +#define InlineBoxTraversal_h + +#include "platform/wtf/Allocator.h" + +namespace blink { + +class InlineBox; + +// This class provides common traveral functions on list of |InlineBox|. +class InlineBoxTraversal final { + STATIC_ONLY(InlineBoxTraversal); + + public: + // TODO(yosin): We should take |bidi_level| from |InlineBox::BidiLevel()|, + // once all call sites satisfy it. + // Find left boundary variations + static InlineBox* FindLeftBoundaryOfBidiRunIgnoringLineBreak( + const InlineBox&, + unsigned bidi_level); + static InlineBox* FindLeftBoundaryOfEntireBidiRun(const InlineBox&, + unsigned bidi_level); + static InlineBox* FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak( + const InlineBox&, + unsigned bidi_level); + + // Find right boundary variations + static InlineBox* FindRightBoundaryOfBidiRunIgnoringLineBreak( + const InlineBox&, + unsigned bidi_level); + static InlineBox* FindRightBoundaryOfEntireBidiRun(const InlineBox&, + unsigned bidi_level); + static InlineBox* FindRightBoundaryOfEntireBidiRunIgnoringLineBreak( + const InlineBox&, + unsigned bidi_level); +}; + +} // namespace blink + +#endif // InlineBoxTraversal_h
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index d4355c8..0fe37bf 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -34,6 +34,7 @@ #include "core/dom/Text.h" #include "core/editing/EditingUtilities.h" #include "core/editing/FrameSelection.h" +#include "core/editing/InlineBoxTraversal.h" #include "core/editing/Position.h" #include "core/editing/PositionIterator.h" #include "core/editing/RenderedPosition.h" @@ -839,41 +840,37 @@ int caret_offset, TextAffinity affinity, TextDirection primary_direction) { - // TODO(yosin): We should move this code fragment to another function to - // remove the scope. InlineBox* inline_box = nullptr; - { - LayoutText* text_layout_object = ToLayoutText(layout_object); + LayoutText* text_layout_object = ToLayoutText(layout_object); - InlineTextBox* candidate = nullptr; + InlineTextBox* candidate = nullptr; - for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { - int caret_min_offset = box->CaretMinOffset(); - int caret_max_offset = box->CaretMaxOffset(); + for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) { + int caret_min_offset = box->CaretMinOffset(); + int caret_max_offset = box->CaretMaxOffset(); - if (caret_offset < caret_min_offset || caret_offset > caret_max_offset || - (caret_offset == caret_max_offset && box->IsLineBreak())) - continue; + if (caret_offset < caret_min_offset || caret_offset > caret_max_offset || + (caret_offset == caret_max_offset && box->IsLineBreak())) + continue; - if (caret_offset > caret_min_offset && caret_offset < caret_max_offset) - return InlineBoxPosition(box, caret_offset); + if (caret_offset > caret_min_offset && caret_offset < caret_max_offset) + return InlineBoxPosition(box, caret_offset); - if (IsCaretAtEdgeOfInlineTextBox(caret_offset, *box, affinity)) { - inline_box = box; - break; - } - - candidate = box; + if (IsCaretAtEdgeOfInlineTextBox(caret_offset, *box, affinity)) { + inline_box = box; + break; } - if (candidate && candidate == text_layout_object->LastTextBox() && - affinity == TextAffinity::kDownstream) { - inline_box = SearchAheadForBetterMatch(text_layout_object); - if (inline_box) - caret_offset = inline_box->CaretMinOffset(); - } - if (!inline_box) - inline_box = candidate; + + candidate = box; } + if (candidate && candidate == text_layout_object->LastTextBox() && + affinity == TextAffinity::kDownstream) { + inline_box = SearchAheadForBetterMatch(text_layout_object); + if (inline_box) + caret_offset = inline_box->CaretMinOffset(); + } + if (!inline_box) + inline_box = candidate; if (!inline_box) return InlineBoxPosition(); @@ -906,11 +903,8 @@ return InlineBoxPosition(inline_box, caret_offset); // For example, abc 123 ^ CBA - while (InlineBox* next_box = inline_box->NextLeafChild()) { - if (next_box->BidiLevel() < level) - break; - inline_box = next_box; - } + inline_box = InlineBoxTraversal::FindRightBoundaryOfEntireBidiRun( + *inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretRightmostOffset()); } @@ -926,11 +920,8 @@ if (next_box && next_box->BidiLevel() == level) return InlineBoxPosition(inline_box, caret_offset); - while (InlineBox* prev_box = inline_box->PrevLeafChild()) { - if (prev_box->BidiLevel() < level) - break; - inline_box = prev_box; - } + inline_box = + InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRun(*inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretLeftmostOffset()); } @@ -939,23 +930,17 @@ if (!prev_box || prev_box->BidiLevel() < level) { // Left edge of a secondary run. Set to the right edge of the entire // run. - while (InlineBox* next_box = - inline_box->NextLeafChildIgnoringLineBreak()) { - if (next_box->BidiLevel() < level) - break; - inline_box = next_box; - } + inline_box = + InlineBoxTraversal::FindRightBoundaryOfEntireBidiRunIgnoringLineBreak( + *inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretRightmostOffset()); } if (prev_box->BidiLevel() > level) { // Right edge of a "tertiary" run. Set to the left edge of that run. - while (InlineBox* tertiary_box = - inline_box->PrevLeafChildIgnoringLineBreak()) { - if (tertiary_box->BidiLevel() <= level) - break; - inline_box = tertiary_box; - } + inline_box = + InlineBoxTraversal::FindLeftBoundaryOfBidiRunIgnoringLineBreak( + *inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretLeftmostOffset()); } return InlineBoxPosition(inline_box, caret_offset); @@ -971,11 +956,9 @@ if (!next_box || next_box->BidiLevel() < level) { // Right edge of a secondary run. Set to the left edge of the entire // run. - while (InlineBox* prev_box = inline_box->PrevLeafChildIgnoringLineBreak()) { - if (prev_box->BidiLevel() < level) - break; - inline_box = prev_box; - } + inline_box = + InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak( + *inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretLeftmostOffset()); } @@ -983,12 +966,8 @@ return InlineBoxPosition(inline_box, caret_offset); // Left edge of a "tertiary" run. Set to the right edge of that run. - while (InlineBox* tertiary_box = - inline_box->NextLeafChildIgnoringLineBreak()) { - if (tertiary_box->BidiLevel() <= level) - break; - inline_box = tertiary_box; - } + inline_box = InlineBoxTraversal::FindRightBoundaryOfBidiRunIgnoringLineBreak( + *inline_box, level); return InlineBoxPosition(inline_box, inline_box->CaretRightmostOffset()); }
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp index 1d9672e..4e0da7b 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp
@@ -206,6 +206,14 @@ LayoutUnit(line_direction_point - absolute_block_point.Y())); } +bool InSameLine(const Node& node, const VisiblePosition& visible_position) { + if (!node.GetLayoutObject()) + return false; + return InSameLine(CreateVisiblePosition( + FirstPositionInOrBeforeNode(const_cast<Node*>(&node))), + visible_position); +} + } // namespace // FIXME: consolidate with code in previousLinePosition. @@ -218,11 +226,7 @@ HighestEditableRoot(visible_position.DeepEquivalent(), editable_type); Node* previous_node = PreviousLeafWithSameEditability(node, editable_type); - while (previous_node && - (!previous_node->GetLayoutObject() || - InSameLine( - CreateVisiblePosition(FirstPositionInOrBeforeNode(previous_node)), - visible_position))) { + while (previous_node && InSameLine(*previous_node, visible_position)) { previous_node = PreviousLeafWithSameEditability(previous_node, editable_type); } @@ -254,10 +258,7 @@ ContainerNode* highest_root = HighestEditableRoot(visible_position.DeepEquivalent(), editable_type); Node* next_node = NextLeafWithSameEditability(node, editable_type); - while (next_node && (!next_node->GetLayoutObject() || - InSameLine(CreateVisiblePosition( - FirstPositionInOrBeforeNode(next_node)), - visible_position))) + while (next_node && InSameLine(*next_node, visible_position)) next_node = NextLeafWithSameEditability(next_node, kContentIsEditable); while (next_node && !next_node->IsShadowRoot()) {
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp index 99a9749b..bb30a26 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.cpp
@@ -114,16 +114,6 @@ return WebRect(); } -bool WebRemoteFrameImpl::HasHorizontalScrollbar() const { - NOTREACHED(); - return false; -} - -bool WebRemoteFrameImpl::HasVerticalScrollbar() const { - NOTREACHED(); - return false; -} - WebView* WebRemoteFrameImpl::View() const { if (!GetFrame()) { return nullptr;
diff --git a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h index 95cec3e6..5fcf354e 100644 --- a/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h +++ b/third_party/WebKit/Source/core/exported/WebRemoteFrameImpl.h
@@ -39,8 +39,6 @@ WebSize ContentsSize() const override; bool HasVisibleContent() const override; WebRect VisibleContentRect() const override; - bool HasHorizontalScrollbar() const override; - bool HasVerticalScrollbar() const override; WebView* View() const override; WebDocument GetDocument() const override; WebPerformance Performance() const override;
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index 07e809a..348a1e2 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -15,12 +15,12 @@ namespace { enum Milestone { - M59, M60, M61, M62, M63, M64, + M65, }; const char* milestoneString(Milestone milestone) { @@ -28,8 +28,6 @@ // https://www.chromium.org/developers/calendar switch (milestone) { - case M59: - return "M59, around June 2017"; case M60: return "M60, around August 2017"; case M61: @@ -40,6 +38,8 @@ return "M63, around December 2017"; case M64: return "M64, around January 2018"; + case M65: + return "M65, around March 2018"; } NOTREACHED(); @@ -439,11 +439,16 @@ "The CredentialsContainer.requireUserMediation method", "the CredentialsContainer.preventSilentAccess method", M62, "4781762488041472"); - case WebFeature::kDeprecatedTimingFunctionStepMiddle: return replacedWillBeRemoved( "The step timing function with step position 'middle'", "the frames timing function", M62, "5189363944128512"); + case WebFeature::kHTMLImportsHasStyleSheets: + return String::Format( + "Styling master document from stylesheets defined in HTML Imports " + "is deprecated, and is planned to be removed in %s. Please refer to " + "https://goo.gl/EGXzpw for possible migration paths.", + milestoneString(M65)); // Features that aren't deprecated don't have a deprecation message. default:
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp index 3a72d1e..f409302 100644 --- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp +++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
@@ -225,7 +225,6 @@ WebViewBase* WebViewHelper::InitializeWithOpener( WebFrame* opener, - bool enable_javascript, TestWebFrameClient* web_frame_client, TestWebViewClient* web_view_client, TestWebWidgetClient* web_widget_client, @@ -245,7 +244,7 @@ web_widget_client = web_view_client->WidgetClient(); web_view_ = static_cast<WebViewBase*>( WebView::Create(web_view_client, kWebPageVisibilityStateVisible)); - web_view_->GetSettings()->SetJavaScriptEnabled(enable_javascript); + web_view_->GetSettings()->SetJavaScriptEnabled(true); web_view_->GetSettings()->SetPluginsEnabled(true); // Enable (mocked) network loads of image URLs, as this simplifies // the completion of resource loads upon test shutdown & helps avoid @@ -276,25 +275,22 @@ } WebViewBase* WebViewHelper::Initialize( - bool enable_javascript, TestWebFrameClient* web_frame_client, TestWebViewClient* web_view_client, TestWebWidgetClient* web_widget_client, void (*update_settings_func)(WebSettings*)) { - return InitializeWithOpener(nullptr, enable_javascript, web_frame_client, - web_view_client, web_widget_client, - update_settings_func); + return InitializeWithOpener(nullptr, web_frame_client, web_view_client, + web_widget_client, update_settings_func); } WebViewBase* WebViewHelper::InitializeAndLoad( const std::string& url, - bool enable_javascript, TestWebFrameClient* web_frame_client, TestWebViewClient* web_view_client, TestWebWidgetClient* web_widget_client, void (*update_settings_func)(WebSettings*)) { - Initialize(enable_javascript, web_frame_client, web_view_client, - web_widget_client, update_settings_func); + Initialize(web_frame_client, web_view_client, web_widget_client, + update_settings_func); LoadFrame(WebView()->MainFrame(), url);
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h index acd8b7a..9d1c84a 100644 --- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.h +++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.h
@@ -229,15 +229,13 @@ // WebViewHelper. WebViewBase* InitializeWithOpener( WebFrame* opener, - bool enable_javascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr, void (*update_settings_func)(WebSettings*) = nullptr); // Same as initializeWithOpener(), but always sets the opener to null. - WebViewBase* Initialize(bool enable_javascript = false, - TestWebFrameClient* = nullptr, + WebViewBase* Initialize(TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr, void (*update_settings_func)(WebSettings*) = 0); @@ -246,7 +244,6 @@ // returns once the load is complete. WebViewBase* InitializeAndLoad( const std::string& url, - bool enable_javascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr,
diff --git a/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp b/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp index 4e2258ef..3098ff2 100644 --- a/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp +++ b/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
@@ -36,6 +36,7 @@ #include "core/dom/custom/V0CustomElement.h" #include "core/dom/custom/V0CustomElementMicrotaskImportStep.h" #include "core/dom/custom/V0CustomElementSyncMicrotaskQueue.h" +#include "core/frame/Deprecation.h" #include "core/frame/UseCounter.h" #include "core/html/imports/HTMLImportChildClient.h" #include "core/html/imports/HTMLImportLoader.h" @@ -79,8 +80,8 @@ void HTMLImportChild::DidFinishLoading() { StateWillChange(); if (GetDocument() && GetDocument()->GetStyleEngine().HasStyleSheets()) { - UseCounter::Count(Root()->GetDocument(), - WebFeature::kHTMLImportsHasStyleSheets); + Deprecation::CountDeprecation(Root()->GetDocument(), + WebFeature::kHTMLImportsHasStyleSheets); } V0CustomElement::DidFinishLoadingImport(*(Root()->GetDocument())); }
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp index d55bf53..1b0e7390 100644 --- a/third_party/WebKit/Source/core/input/EventHandler.cpp +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -254,8 +254,8 @@ if (!controller) return; controller->StartMiddleClickAutoscroll( - ToLayoutBox(layout_object), - mouse_event_manager_->LastKnownMousePosition()); + layout_object->GetFrame(), mouse_event_manager_->LastKnownMousePosition(), + mouse_event_manager_->LastKnownMousePositionGlobal()); mouse_event_manager_->InvalidateClick(); } @@ -310,6 +310,7 @@ } void EventHandler::StopAutoscroll() { + scroll_manager_->StopMiddleClickAutoscroll(); scroll_manager_->StopAutoscroll(); } @@ -628,7 +629,7 @@ // return. bool is_middle_click_autoscroll_in_progress = scroll_manager_->MiddleClickAutoscrollInProgress(); - scroll_manager_->StopAutoscroll(); + scroll_manager_->StopMiddleClickAutoscroll(); if (is_middle_click_autoscroll_in_progress) { // We invalidate the click when exiting middle click auto scroll so that // we don't inadvertently navigate away from the current page (e.g. the @@ -783,6 +784,19 @@ mouse_event_manager_->CancelFakeMouseMoveEvent(); mouse_event_manager_->HandleSvgPanIfNeeded(false); + if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()) { + if (Page* page = frame_->GetPage()) { + if (mouse_event.GetType() == WebInputEvent::kMouseLeave && + mouse_event.button != WebPointerProperties::Button::kMiddle) { + page->GetAutoscrollController().StopMiddleClickAutoscroll(frame_); + } else { + page->GetAutoscrollController().HandleMouseMoveForMiddleClickAutoscroll( + frame_, mouse_event_manager_->LastKnownMousePositionGlobal(), + mouse_event.button == WebPointerProperties::Button::kMiddle); + } + } + } + if (frame_set_being_resized_) { return UpdatePointerTargetAndDispatchEvents( EventTypeNames::mousemove, frame_set_being_resized_.Get(), String(), @@ -914,9 +928,12 @@ frame_->Selection().SetCaretBlinkingSuspended(false); if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()) { - if (Page* page = frame_->GetPage()) + if (Page* page = frame_->GetPage()) { page->GetAutoscrollController() - .HandleMouseReleaseForMiddleClickAutoscroll(frame_, mouse_event); + .HandleMouseReleaseForMiddleClickAutoscroll( + frame_, + mouse_event.button == WebPointerProperties::Button::kMiddle); + } } mouse_event_manager_->SetMousePressed(false);
diff --git a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp index 72639a8..f718f62 100644 --- a/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp +++ b/third_party/WebKit/Source/core/input/KeyboardEventManager.cpp
@@ -177,7 +177,7 @@ // we want to stop. if (initial_key_event.GetType() == WebInputEvent::kKeyDown || initial_key_event.GetType() == WebInputEvent::kRawKeyDown) - scroll_manager_->StopAutoscroll(); + scroll_manager_->StopMiddleClickAutoscroll(); // If we were in panscroll mode, we swallow the key event return WebInputEventResult::kHandledSuppressed;
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.cpp b/third_party/WebKit/Source/core/input/MouseEventManager.cpp index 5fb02ce..2a74e8db 100644 --- a/third_party/WebKit/Source/core/input/MouseEventManager.cpp +++ b/third_party/WebKit/Source/core/input/MouseEventManager.cpp
@@ -91,8 +91,8 @@ mouse_down_may_start_drag_ = false; captures_dragging_ = false; is_mouse_position_unknown_ = true; - last_known_mouse_position_ = IntPoint(); - last_known_mouse_global_position_ = IntPoint(); + last_known_mouse_position_ = FloatPoint(); + last_known_mouse_global_position_ = FloatPoint(); mouse_pressed_ = false; click_count_ = 0; click_element_ = nullptr; @@ -567,14 +567,17 @@ } IntPoint MouseEventManager::LastKnownMousePosition() { - return last_known_mouse_position_; + return FlooredIntPoint(last_known_mouse_position_); +} + +FloatPoint MouseEventManager::LastKnownMousePositionGlobal() { + return last_known_mouse_global_position_; } void MouseEventManager::SetLastKnownMousePosition(const WebMouseEvent& event) { is_mouse_position_unknown_ = false; - last_known_mouse_position_ = FlooredIntPoint(event.PositionInRootFrame()); - last_known_mouse_global_position_ = - IntPoint(event.PositionInScreen().x, event.PositionInScreen().y); + last_known_mouse_position_ = event.PositionInRootFrame(); + last_known_mouse_global_position_ = event.PositionInScreen(); } void MouseEventManager::DispatchFakeMouseMoveEventSoon() { @@ -668,7 +671,7 @@ WebInputEventResult MouseEventManager::HandleMouseReleaseEvent( const MouseEventWithHitTestResults& event) { AutoscrollController* controller = scroll_manager_->GetAutoscrollController(); - if (controller && controller->AutoscrollInProgress()) + if (controller && controller->SelectionAutoscrollInProgress()) scroll_manager_->StopAutoscroll(); return frame_->GetEventHandler() @@ -682,7 +685,7 @@ frame_->GetEventHandler() .GetSelectionController() .UpdateSelectionForMouseDrag(mouse_press_node_, drag_start_pos_, - last_known_mouse_position_); + FlooredIntPoint(last_known_mouse_position_)); } bool MouseEventManager::HandleDragDropIfPossible( @@ -781,7 +784,7 @@ frame_->GetEventHandler().GetSelectionController().HandleMouseDraggedEvent( event, mouse_down_pos_, drag_start_pos_, mouse_press_node_.Get(), - last_known_mouse_position_); + FlooredIntPoint(last_known_mouse_position_)); // The call into HandleMouseDraggedEvent may have caused a re-layout, // so get the LayoutObject again.
diff --git a/third_party/WebKit/Source/core/input/MouseEventManager.h b/third_party/WebKit/Source/core/input/MouseEventManager.h index b0086b0..0a1f7b40 100644 --- a/third_party/WebKit/Source/core/input/MouseEventManager.h +++ b/third_party/WebKit/Source/core/input/MouseEventManager.h
@@ -126,7 +126,9 @@ // refactoring to be able to remove the dependency from EventHandler. Node* GetNodeUnderMouse(); bool IsMousePositionUnknown(); + // TODO(aelias): Make LastKnownMousePosition return FloatPoint. IntPoint LastKnownMousePosition(); + FloatPoint LastKnownMousePositionGlobal(); bool MousePressed(); void SetMousePressed(bool); @@ -211,8 +213,8 @@ // The last mouse movement position this frame has seen in root frame // coordinates. - IntPoint last_known_mouse_position_; - IntPoint last_known_mouse_global_position_; + FloatPoint last_known_mouse_position_; + FloatPoint last_known_mouse_global_position_; unsigned is_mouse_position_unknown_ : 1; // Current button-press state for mouse/mouse-like-stylus.
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp index 027fda0..9ce05ac6 100644 --- a/third_party/WebKit/Source/core/input/ScrollManager.cpp +++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
@@ -68,6 +68,11 @@ controller->StopAutoscroll(); } +void ScrollManager::StopMiddleClickAutoscroll() { + if (AutoscrollController* controller = GetAutoscrollController()) + controller->StopMiddleClickAutoscroll(frame_); +} + bool ScrollManager::MiddleClickAutoscrollInProgress() const { return GetAutoscrollController() && GetAutoscrollController()->MiddleClickAutoscrollInProgress();
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.h b/third_party/WebKit/Source/core/input/ScrollManager.h index 58e0d14..bbbe249 100644 --- a/third_party/WebKit/Source/core/input/ScrollManager.h +++ b/third_party/WebKit/Source/core/input/ScrollManager.h
@@ -42,6 +42,7 @@ void Clear(); bool MiddleClickAutoscrollInProgress() const; + void StopMiddleClickAutoscroll(); AutoscrollController* GetAutoscrollController() const; void StopAutoscroll();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 21f1a31..f448d46 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -637,7 +637,7 @@ HTMLFrameElementBase* frame_element_base = ToHTMLFrameElementBase(owner_element); if (Page* page = frame_view->GetFrame().GetPage()) { - return page->GetAutoscrollController().AutoscrollInProgress() && + return page->GetAutoscrollController().SelectionAutoscrollInProgress() && frame_element_base->ScrollingMode() == kScrollbarAlwaysOff; } } @@ -720,7 +720,10 @@ return; } - if (GetFrame()->GetPage()->GetAutoscrollController().AutoscrollInProgress()) + if (GetFrame() + ->GetPage() + ->GetAutoscrollController() + .SelectionAutoscrollInProgress()) parent_box = EnclosingScrollableBox(); if (parent_box) {
diff --git a/third_party/WebKit/Source/core/mojo/BUILD.gn b/third_party/WebKit/Source/core/mojo/BUILD.gn index 202d78e..aaa52ac 100644 --- a/third_party/WebKit/Source/core/mojo/BUILD.gn +++ b/third_party/WebKit/Source/core/mojo/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//mojo/public/tools/bindings/mojom.gni") import("//third_party/WebKit/Source/core/core.gni") blink_core_sources("mojo") { @@ -23,3 +24,39 @@ "//services/service_manager/public/cpp", ] } + +source_set("unit_tests") { + testonly = true + sources = [ + "tests/JsToCppTest.cpp", + ] + + data = [ + "tests/JsToCppTest.js", + ] + + configs += [ + "//third_party/WebKit/Source/core:blink_core_pch", + "//third_party/WebKit/Source:config", + "//third_party/WebKit/Source:inside_blink", + ] + + deps = [ + ":test_bindings_blink", + "//mojo/public/cpp/bindings", + "//testing/gtest", + "//third_party/WebKit/Source/core:core", + "//third_party/WebKit/Source/core:testing", + ] + + data_deps = [ + ":test_bindings", # For JS bindings: crbug.com/729649. + "//mojo/public/js:new_bindings", + ] +} + +mojom("test_bindings") { + sources = [ + "tests/JsToCpp.mojom", + ] +}
diff --git a/mojo/edk/js/tests/js_to_cpp.mojom b/third_party/WebKit/Source/core/mojo/tests/JsToCpp.mojom similarity index 100% rename from mojo/edk/js/tests/js_to_cpp.mojom rename to third_party/WebKit/Source/core/mojo/tests/JsToCpp.mojom
diff --git a/third_party/WebKit/Source/core/mojo/tests/JsToCppTest.cpp b/third_party/WebKit/Source/core/mojo/tests/JsToCppTest.cpp new file mode 100644 index 0000000..08411ee3 --- /dev/null +++ b/third_party/WebKit/Source/core/mojo/tests/JsToCppTest.cpp
@@ -0,0 +1,436 @@ +// 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. + +#include "bindings/core/v8/ScriptController.h" +#include "bindings/core/v8/ScriptSourceCode.h" +#include "bindings/core/v8/V8BindingForCore.h" +#include "bindings/core/v8/V8BindingForTesting.h" +#include "bindings/core/v8/V8ScriptRunner.h" +#include "core/frame/Settings.h" +#include "core/mojo/MojoHandle.h" +#include "core/page/Page.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/wait.h" +#include "platform/testing/UnitTestHelpers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/Source/core/mojo/tests/JsToCpp.mojom-blink.h" + +namespace blink { +namespace { + +// Global value updated by some checks to prevent compilers from optimizing +// reads out of existence. +uint32_t g_waste_accumulator = 0; + +// Negative numbers with different values in each byte, the last of +// which can survive promotion to double and back. +const int8_t kExpectedInt8Value = -65; +const int16_t kExpectedInt16Value = -16961; +const int32_t kExpectedInt32Value = -1145258561; +const int64_t kExpectedInt64Value = -77263311946305LL; + +// Positive numbers with different values in each byte, the last of +// which can survive promotion to double and back. +const uint8_t kExpectedUInt8Value = 65; +const uint16_t kExpectedUInt16Value = 16961; +const uint32_t kExpectedUInt32Value = 1145258561; +const uint64_t kExpectedUInt64Value = 77263311946305LL; + +// Double/float values, including special case constants. +const double kExpectedDoubleVal = 3.14159265358979323846; +const double kExpectedDoubleInf = std::numeric_limits<double>::infinity(); +const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN(); +const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal); +const float kExpectedFloatInf = std::numeric_limits<float>::infinity(); +const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN(); + +// NaN has the property that it is not equal to itself. +#define EXPECT_NAN(x) EXPECT_NE(x, x) + +String MojoBindingsScriptPath() { + String filepath = testing::ExecutableDir(); + filepath.append("/gen/mojo/public/js/mojo_bindings.js"); + return filepath; +} + +String TestBindingsScriptPath() { + String filepath = testing::ExecutableDir(); + filepath.append( + "/gen/third_party/WebKit/Source/core/mojo/tests/JsToCpp.mojom.js"); + return filepath; +} + +String TestScriptPath() { + String filepath = testing::BlinkRootDir(); + filepath.append("/Source/core/mojo/tests/JsToCppTest.js"); + return filepath; +} + +v8::Local<v8::Value> ExecuteScript(const String& script_path, + LocalFrame& frame) { + RefPtr<SharedBuffer> script_src = testing::ReadFromFile(script_path); + return frame.GetScriptController().ExecuteScriptInMainWorldAndReturnValue( + ScriptSourceCode(String(script_src->Data(), script_src->size()))); +} + +void CheckDataPipe(mojo::DataPipeConsumerHandle data_pipe_handle) { + MojoResult result = Wait(data_pipe_handle, MOJO_HANDLE_SIGNAL_READABLE); + EXPECT_EQ(MOJO_RESULT_OK, result); + + const void* buffer = nullptr; + unsigned num_bytes = 0; + result = BeginReadDataRaw(data_pipe_handle, &buffer, &num_bytes, + MOJO_READ_DATA_FLAG_NONE); + EXPECT_EQ(MOJO_RESULT_OK, result); + EXPECT_EQ(64u, num_bytes); + for (unsigned i = 0; i < num_bytes; ++i) { + EXPECT_EQ(i, static_cast<unsigned>(static_cast<const char*>(buffer)[i])); + } + EndReadDataRaw(data_pipe_handle, num_bytes); +} + +void CheckMessagePipe(mojo::MessagePipeHandle message_pipe_handle) { + MojoResult result = Wait(message_pipe_handle, MOJO_HANDLE_SIGNAL_READABLE); + EXPECT_EQ(MOJO_RESULT_OK, result); + + std::vector<uint8_t> bytes; + std::vector<mojo::ScopedHandle> handles; + result = ReadMessageRaw(message_pipe_handle, &bytes, &handles, 0); + EXPECT_EQ(MOJO_RESULT_OK, result); + EXPECT_EQ(64u, bytes.size()); + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(255 - i, bytes[i]); + } +} + +js_to_cpp::blink::EchoArgsPtr BuildSampleEchoArgs() { + auto args = js_to_cpp::blink::EchoArgs::New(); + args->si64 = kExpectedInt64Value; + args->si32 = kExpectedInt32Value; + args->si16 = kExpectedInt16Value; + args->si8 = kExpectedInt8Value; + args->ui64 = kExpectedUInt64Value; + args->ui32 = kExpectedUInt32Value; + args->ui16 = kExpectedUInt16Value; + args->ui8 = kExpectedUInt8Value; + args->float_val = kExpectedFloatVal; + args->float_inf = kExpectedFloatInf; + args->float_nan = kExpectedFloatNan; + args->double_val = kExpectedDoubleVal; + args->double_inf = kExpectedDoubleInf; + args->double_nan = kExpectedDoubleNan; + args->name = "coming"; + args->string_array.emplace(3); + (*args->string_array)[0] = "one"; + (*args->string_array)[1] = "two"; + (*args->string_array)[2] = "three"; + return args; +} + +void CheckSampleEchoArgs(const js_to_cpp::blink::EchoArgsPtr& arg) { + EXPECT_EQ(kExpectedInt64Value, arg->si64); + EXPECT_EQ(kExpectedInt32Value, arg->si32); + EXPECT_EQ(kExpectedInt16Value, arg->si16); + EXPECT_EQ(kExpectedInt8Value, arg->si8); + EXPECT_EQ(kExpectedUInt64Value, arg->ui64); + EXPECT_EQ(kExpectedUInt32Value, arg->ui32); + EXPECT_EQ(kExpectedUInt16Value, arg->ui16); + EXPECT_EQ(kExpectedUInt8Value, arg->ui8); + EXPECT_EQ(kExpectedFloatVal, arg->float_val); + EXPECT_EQ(kExpectedFloatInf, arg->float_inf); + EXPECT_NAN(arg->float_nan); + EXPECT_EQ(kExpectedDoubleVal, arg->double_val); + EXPECT_EQ(kExpectedDoubleInf, arg->double_inf); + EXPECT_NAN(arg->double_nan); + EXPECT_EQ(String("coming"), arg->name); + EXPECT_EQ(String("one"), (*arg->string_array)[0]); + EXPECT_EQ(String("two"), (*arg->string_array)[1]); + EXPECT_EQ(String("three"), (*arg->string_array)[2]); + CheckDataPipe(arg->data_handle.get()); + CheckMessagePipe(arg->message_handle.get()); +} + +void CheckSampleEchoArgsList(const js_to_cpp::blink::EchoArgsListPtr& list) { + if (list.is_null()) + return; + CheckSampleEchoArgs(list->item); + CheckSampleEchoArgsList(list->next); +} + +// More forgiving checks are needed in the face of potentially corrupt +// messages. The values don't matter so long as all accesses are within +// bounds. +void CheckCorruptedString(const String& arg) { + for (size_t i = 0; i < arg.length(); ++i) + g_waste_accumulator += arg[i]; +} + +void CheckCorruptedStringArray(const Optional<Vector<String>>& string_array) { + if (!string_array) + return; + for (size_t i = 0; i < string_array->size(); ++i) + CheckCorruptedString((*string_array)[i]); +} + +void CheckCorruptedDataPipe(mojo::DataPipeConsumerHandle data_pipe_handle) { + unsigned char buffer[100]; + uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); + MojoResult result = ReadDataRaw(data_pipe_handle, buffer, &buffer_size, + MOJO_READ_DATA_FLAG_NONE); + if (result != MOJO_RESULT_OK) + return; + for (uint32_t i = 0; i < buffer_size; ++i) + g_waste_accumulator += buffer[i]; +} + +void CheckCorruptedMessagePipe(mojo::MessagePipeHandle message_pipe_handle) { + std::vector<uint8_t> bytes; + std::vector<mojo::ScopedHandle> handles; + MojoResult result = ReadMessageRaw(message_pipe_handle, &bytes, &handles, 0); + if (result != MOJO_RESULT_OK) + return; + for (uint32_t i = 0; i < bytes.size(); ++i) + g_waste_accumulator += bytes[i]; +} + +void CheckCorruptedEchoArgs(const js_to_cpp::blink::EchoArgsPtr& arg) { + if (arg.is_null()) + return; + CheckCorruptedString(arg->name); + CheckCorruptedStringArray(arg->string_array); + if (arg->data_handle.is_valid()) + CheckCorruptedDataPipe(arg->data_handle.get()); + if (arg->message_handle.is_valid()) + CheckCorruptedMessagePipe(arg->message_handle.get()); +} + +void CheckCorruptedEchoArgsList(const js_to_cpp::blink::EchoArgsListPtr& list) { + if (list.is_null()) + return; + CheckCorruptedEchoArgs(list->item); + CheckCorruptedEchoArgsList(list->next); +} + +// Base Provider implementation class. It's expected that tests subclass and +// override the appropriate Provider functions. When test is done quit the +// run_loop(). +class CppSideConnection : public js_to_cpp::blink::CppSide { + public: + CppSideConnection() : mishandled_messages_(0), binding_(this) {} + ~CppSideConnection() override {} + + void set_js_side(js_to_cpp::blink::JsSidePtr js_side) { + js_side_ = std::move(js_side); + } + js_to_cpp::blink::JsSide* js_side() { return js_side_.get(); } + + void Bind(mojo::InterfaceRequest<js_to_cpp::blink::CppSide> request) { + binding_.Bind(std::move(request)); + // Keep the pipe open even after validation errors. + binding_.EnableTestingMode(); + } + + // js_to_cpp::CppSide: + void StartTest() override { NOTREACHED(); } + + void TestFinished() override { NOTREACHED(); } + + void PingResponse() override { mishandled_messages_ += 1; } + + void EchoResponse(js_to_cpp::blink::EchoArgsListPtr list) override { + mishandled_messages_ += 1; + } + + void BitFlipResponse( + js_to_cpp::blink::EchoArgsListPtr list, + js_to_cpp::blink::ForTestingAssociatedPtrInfo not_used) override { + mishandled_messages_ += 1; + } + + void BackPointerResponse(js_to_cpp::blink::EchoArgsListPtr list) override { + mishandled_messages_ += 1; + } + + protected: + js_to_cpp::blink::JsSidePtr js_side_; + int mishandled_messages_; + mojo::Binding<js_to_cpp::blink::CppSide> binding_; +}; + +// Trivial test to verify a message sent from JS is received. +class PingCppSideConnection : public CppSideConnection { + public: + PingCppSideConnection() : got_message_(false) {} + ~PingCppSideConnection() override {} + + // js_to_cpp::CppSide: + void StartTest() override { js_side_->Ping(); } + + void PingResponse() override { + got_message_ = true; + testing::ExitRunLoop(); + } + + bool DidSucceed() { return got_message_ && !mishandled_messages_; } + + private: + bool got_message_; +}; + +// Test that parameters are passed with correct values. +class EchoCppSideConnection : public CppSideConnection { + public: + EchoCppSideConnection() : message_count_(0), termination_seen_(false) {} + ~EchoCppSideConnection() override {} + + // js_to_cpp::CppSide: + void StartTest() override { + js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs()); + } + + void EchoResponse(js_to_cpp::blink::EchoArgsListPtr list) override { + message_count_ += 1; + + const js_to_cpp::blink::EchoArgsPtr& special_arg = list->item; + EXPECT_EQ(-1, special_arg->si64); + EXPECT_EQ(-1, special_arg->si32); + EXPECT_EQ(-1, special_arg->si16); + EXPECT_EQ(-1, special_arg->si8); + EXPECT_EQ(String("going"), special_arg->name); + CheckDataPipe(special_arg->data_handle.get()); + CheckMessagePipe(special_arg->message_handle.get()); + + CheckSampleEchoArgsList(list->next); + } + + void TestFinished() override { + termination_seen_ = true; + testing::ExitRunLoop(); + } + + bool DidSucceed() { + return termination_seen_ && !mishandled_messages_ && + message_count_ == kExpectedMessageCount; + } + + private: + static const int kExpectedMessageCount = 10; + int message_count_; + bool termination_seen_; +}; + +// Test that corrupted messages don't wreak havoc. +class BitFlipCppSideConnection : public CppSideConnection { + public: + BitFlipCppSideConnection() : termination_seen_(false) {} + ~BitFlipCppSideConnection() override {} + + // js_to_cpp::CppSide: + void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); } + + void BitFlipResponse( + js_to_cpp::blink::EchoArgsListPtr list, + js_to_cpp::blink::ForTestingAssociatedPtrInfo not_used) override { + CheckCorruptedEchoArgsList(list); + } + + void TestFinished() override { + termination_seen_ = true; + testing::ExitRunLoop(); + } + + bool DidSucceed() { return termination_seen_; } + + private: + bool termination_seen_; +}; + +// Test that severely random messages don't wreak havoc. +class BackPointerCppSideConnection : public CppSideConnection { + public: + BackPointerCppSideConnection() : termination_seen_(false) {} + ~BackPointerCppSideConnection() override {} + + // js_to_cpp::CppSide: + void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); } + + void BackPointerResponse(js_to_cpp::blink::EchoArgsListPtr list) override { + CheckCorruptedEchoArgsList(list); + } + + void TestFinished() override { + termination_seen_ = true; + testing::ExitRunLoop(); + } + + bool DidSucceed() { return termination_seen_; } + + private: + bool termination_seen_; +}; + +class JsToCppTest : public ::testing::Test { + public: + void RunTest(CppSideConnection* cpp_side) { + js_to_cpp::blink::CppSidePtr cpp_side_ptr; + cpp_side->Bind(MakeRequest(&cpp_side_ptr)); + + js_to_cpp::blink::JsSidePtr js_side_ptr; + auto js_side_request = MakeRequest(&js_side_ptr); + js_side_ptr->SetCppSide(std::move(cpp_side_ptr)); + cpp_side->set_js_side(std::move(js_side_ptr)); + + V8TestingScope scope; + scope.GetPage().GetSettings().SetScriptEnabled(true); + ExecuteScript(MojoBindingsScriptPath(), scope.GetFrame()); + ExecuteScript(TestBindingsScriptPath(), scope.GetFrame()); + + v8::Local<v8::Value> start_fn = + ExecuteScript(TestScriptPath(), scope.GetFrame()); + ASSERT_FALSE(start_fn.IsEmpty()); + ASSERT_TRUE(start_fn->IsFunction()); + v8::Local<v8::Object> global_proxy = scope.GetContext()->Global(); + v8::Local<v8::Value> args[1] = { + ToV8(MojoHandle::Create( + mojo::ScopedHandle::From(js_side_request.PassMessagePipe())), + global_proxy, scope.GetIsolate())}; + V8ScriptRunner::CallFunction( + start_fn.As<v8::Function>(), scope.GetExecutionContext(), global_proxy, + WTF_ARRAY_LENGTH(args), args, scope.GetIsolate()); + testing::EnterRunLoop(); + } +}; + +TEST_F(JsToCppTest, Ping) { + PingCppSideConnection cpp_side_connection; + RunTest(&cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); +} + +TEST_F(JsToCppTest, Echo) { + EchoCppSideConnection cpp_side_connection; + RunTest(&cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); +} + +TEST_F(JsToCppTest, BitFlip) { + // These tests generate a lot of expected validation errors. Suppress logging. + mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; + + BitFlipCppSideConnection cpp_side_connection; + RunTest(&cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); +} + +TEST_F(JsToCppTest, BackPointer) { + // These tests generate a lot of expected validation errors. Suppress logging. + mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; + + BackPointerCppSideConnection cpp_side_connection; + RunTest(&cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); +} + +} // namespace +} // namespace blink
diff --git a/mojo/edk/js/tests/js_to_cpp_tests.js b/third_party/WebKit/Source/core/mojo/tests/JsToCppTest.js similarity index 74% rename from mojo/edk/js/tests/js_to_cpp_tests.js rename to third_party/WebKit/Source/core/mojo/tests/JsToCppTest.js index 6ffce09..139687a 100644 --- a/mojo/edk/js/tests/js_to_cpp_tests.js +++ b/third_party/WebKit/Source/core/mojo/tests/JsToCppTest.js
@@ -2,26 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -define('mojo/edk/js/tests/js_to_cpp_tests', [ - 'console', - 'mojo/edk/js/tests/js_to_cpp.mojom', - 'mojo/public/js/bindings', - 'mojo/public/js/connector', - 'mojo/public/js/core', -], function (console, jsToCpp, bindings, connector, core) { +(function () { var retainedJsSide; - var retainedJsSideStub; var sampleData; var sampleMessage; var BAD_VALUE = 13; var DATA_PIPE_PARAMS = { - flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, elementNumBytes: 1, capacityNumBytes: 64 }; function JsSideConnection() { - this.binding = new bindings.Binding(jsToCpp.JsSide, this); + this.binding = new mojo.Binding(jsToCpp.JsSide, this); } JsSideConnection.prototype.setCppSide = function(cppSide) { @@ -55,13 +47,13 @@ arg.si8 = BAD_VALUE; for (i = 0; i < numIterations; ++i) { - dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS); - dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS); - messagePipe1 = core.createMessagePipe(); - messagePipe2 = core.createMessagePipe(); + dataPipe1 = Mojo.createDataPipe(DATA_PIPE_PARAMS); + dataPipe2 = Mojo.createDataPipe(DATA_PIPE_PARAMS); + messagePipe1 = Mojo.createMessagePipe(); + messagePipe2 = Mojo.createMessagePipe(); - arg.data_handle = dataPipe1.consumerHandle; - arg.message_handle = messagePipe1.handle1; + arg.dataHandle = dataPipe1.consumer; + arg.messageHandle = messagePipe1.handle1; specialArg = new jsToCpp.EchoArgs(); specialArg.si64 = -1; @@ -69,20 +61,19 @@ specialArg.si16 = -1; specialArg.si8 = -1; specialArg.name = 'going'; - specialArg.data_handle = dataPipe2.consumerHandle; - specialArg.message_handle = messagePipe2.handle1; + specialArg.dataHandle = dataPipe2.consumer; + specialArg.messageHandle = messagePipe2.handle1; writeDataPipe(dataPipe1, sampleData); writeDataPipe(dataPipe2, sampleData); writeMessagePipe(messagePipe1, sampleMessage); writeMessagePipe(messagePipe2, sampleMessage); - this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg)); - core.close(dataPipe1.producerHandle); - core.close(dataPipe2.producerHandle); - core.close(messagePipe1.handle0); - core.close(messagePipe2.handle0); + dataPipe1.producer.close(); + dataPipe2.producer.close(); + messagePipe1.handle0.close(); + messagePipe2.handle0.close(); } this.cppSide_.testFinished(); }; @@ -91,7 +82,7 @@ var iteration = 0; var dataPipe; var messagePipe; - var proto = connector.Connector.prototype; + var proto = mojo.internal.Connector.prototype; var stopSignalled = false; proto.realAccept = proto.accept; @@ -110,13 +101,13 @@ }; while (!stopSignalled) { - messagePipe = core.createMessagePipe(); + messagePipe = Mojo.createMessagePipe(); writeMessagePipe(messagePipe, sampleMessage); - arg.message_handle = messagePipe.handle1; + arg.messageHandle = messagePipe.handle1; this.cppSide_.bitFlipResponse(createEchoArgsList(arg), null); - core.close(messagePipe.handle0); + messagePipe.handle0.close(); iteration += 1; } @@ -129,7 +120,7 @@ var iteration = 0; var dataPipe; var messagePipe; - var proto = connector.Connector.prototype; + var proto = mojo.internal.Connector.prototype; var stopSignalled = false; proto.realAccept = proto.accept; @@ -146,13 +137,13 @@ }; while (!stopSignalled) { - messagePipe = core.createMessagePipe(); + messagePipe = Mojo.createMessagePipe(); writeMessagePipe(messagePipe, sampleMessage); - arg.message_handle = messagePipe.handle1; + arg.messageHandle = messagePipe.handle1; this.cppSide_.backPointerResponse(createEchoArgsList(arg)); - core.close(messagePipe.handle0); + messagePipe.handle0.close(); iteration += 1; } @@ -162,10 +153,9 @@ }; function writeDataPipe(pipe, data) { - var writeResult = core.writeData( - pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE); + var writeResult = pipe.producer.writeData(data); - if (writeResult.result != core.RESULT_OK) { + if (writeResult.result != Mojo.RESULT_OK) { console.log('ERROR: Data pipe write result was ' + writeResult.result); return false; } @@ -177,8 +167,8 @@ } function writeMessagePipe(pipe, arrayBuffer) { - var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0); - if (result != core.RESULT_OK) { + var result = pipe.handle0.writeMessage(arrayBuffer, []); + if (result != Mojo.RESULT_OK) { console.log('ERROR: Message pipe write result was ' + result); return false; } @@ -212,4 +202,4 @@ retainedJsSide = new JsSideConnection; retainedJsSide.binding.bind(jsSideRequestHandle); }; -}); +})();
diff --git a/third_party/WebKit/Source/core/mojo/tests/OWNERS b/third_party/WebKit/Source/core/mojo/tests/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/third_party/WebKit/Source/core/mojo/tests/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/WebKit/Source/core/page/AutoscrollController.cpp b/third_party/WebKit/Source/core/page/AutoscrollController.cpp index b0c6af1..22456a37 100644 --- a/third_party/WebKit/Source/core/page/AutoscrollController.cpp +++ b/third_party/WebKit/Source/core/page/AutoscrollController.cpp
@@ -46,22 +46,48 @@ // scrollable element. static const TimeDelta kAutoscrollDelay = TimeDelta::FromSecondsD(0.2); +static const int kNoMiddleClickAutoscrollRadius = 15; + +static const Cursor& MiddleClickAutoscrollCursor(const FloatSize& velocity) { + // At the original click location we draw a 4 arrowed icon. Over this icon + // there won't be any scroll, So don't change the cursor over this area. + bool east = velocity.Width() < 0; + bool west = velocity.Width() > 0; + bool north = velocity.Height() > 0; + bool south = velocity.Height() < 0; + + if (north) { + if (east) + return NorthEastPanningCursor(); + if (west) + return NorthWestPanningCursor(); + return NorthPanningCursor(); + } + if (south) { + if (east) + return SouthEastPanningCursor(); + if (west) + return SouthWestPanningCursor(); + return SouthPanningCursor(); + } + if (east) + return EastPanningCursor(); + if (west) + return WestPanningCursor(); + return MiddlePanningCursor(); +} + AutoscrollController* AutoscrollController::Create(Page& page) { return new AutoscrollController(page); } -AutoscrollController::AutoscrollController(Page& page) - : page_(&page), - autoscroll_layout_object_(nullptr), - pressed_layout_object_(nullptr), - autoscroll_type_(kNoAutoscroll), - did_latch_for_middle_click_autoscroll_(false) {} +AutoscrollController::AutoscrollController(Page& page) : page_(&page) {} DEFINE_TRACE(AutoscrollController) { visitor->Trace(page_); } -bool AutoscrollController::AutoscrollInProgress() const { +bool AutoscrollController::SelectionAutoscrollInProgress() const { return autoscroll_type_ == kAutoscrollForSelection; } @@ -88,7 +114,7 @@ : nullptr; autoscroll_type_ = kAutoscrollForSelection; autoscroll_layout_object_ = scrollable; - StartAutoscroll(); + ScheduleMainThreadAnimation(); } void AutoscrollController::StopAutoscroll() { @@ -96,18 +122,7 @@ pressed_layout_object_->StopAutoscroll(); pressed_layout_object_ = nullptr; } - LayoutBox* scrollable = autoscroll_layout_object_; autoscroll_layout_object_ = nullptr; - - if (!scrollable) - return; - - if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled() && - MiddleClickAutoscrollInProgress()) { - if (LocalFrameView* view = scrollable->GetFrame()->View()) { - view->SetCursor(PointerCursor()); - } - } autoscroll_type_ = kNoAutoscroll; } @@ -127,16 +142,6 @@ LayoutObject* layout_object = autoscroll_layout_object_; - if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()) { - HitTestResult hit_test = - layout_object->GetFrame()->GetEventHandler().HitTestResultAtPoint( - middle_click_autoscroll_start_pos_, - HitTestRequest::kReadOnly | HitTestRequest::kActive); - - if (Node* node_at_point = hit_test.InnerNode()) - layout_object = node_at_point->GetLayoutObject(); - } - while (layout_object && !(layout_object->IsBox() && ToLayoutBox(layout_object)->CanAutoscroll())) layout_object = layout_object->Parent(); @@ -145,7 +150,7 @@ ? ToLayoutBox(layout_object) : nullptr; - if (autoscroll_type_ != kNoAutoscroll && !autoscroll_layout_object_) + if (!autoscroll_layout_object_) autoscroll_type_ = kNoAutoscroll; } @@ -194,43 +199,83 @@ drag_and_drop_autoscroll_start_time_ = event_time; UseCounter::Count(autoscroll_layout_object_->GetFrame(), WebFeature::kDragAndDropScrollStart); - StartAutoscroll(); + ScheduleMainThreadAnimation(); } else if (autoscroll_layout_object_ != scrollable) { drag_and_drop_autoscroll_start_time_ = event_time; autoscroll_layout_object_ = scrollable; } } -void AutoscrollController::HandleMouseReleaseForMiddleClickAutoscroll( +void AutoscrollController::HandleMouseMoveForMiddleClickAutoscroll( LocalFrame* frame, - const WebMouseEvent& mouse_event) { - DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()); - if (!frame->IsMainFrame()) + const FloatPoint& position_global, + bool is_middle_button) { + if (!MiddleClickAutoscrollInProgress()) return; - switch (autoscroll_type_) { - case kAutoscrollForMiddleClick: - if (mouse_event.button == WebPointerProperties::Button::kMiddle) - autoscroll_type_ = kAutoscrollForMiddleClickCanStop; - break; - case kAutoscrollForMiddleClickCanStop: - StopAutoscroll(); - break; - case kAutoscrollForDragAndDrop: - case kAutoscrollForSelection: - case kNoAutoscroll: - // Nothing to do. - break; + + LocalFrameView* view = frame->View(); + if (!view) + return; + + FloatSize distance = + (position_global - middle_click_autoscroll_start_pos_global_) + .ScaledBy(1 / frame->DevicePixelRatio()); + + if (fabs(distance.Width()) <= kNoMiddleClickAutoscrollRadius) + distance.SetWidth(0); + if (fabs(distance.Height()) <= kNoMiddleClickAutoscrollRadius) + distance.SetHeight(0); + + const float kExponent = 2.2f; + const float kMultiplier = -0.000008f; + const int x_signum = (distance.Width() < 0) ? -1 : (distance.Width() > 0); + const int y_signum = (distance.Height() < 0) ? -1 : (distance.Height() > 0); + FloatSize velocity( + pow(fabs(distance.Width()), kExponent) * kMultiplier * x_signum, + pow(fabs(distance.Height()), kExponent) * kMultiplier * y_signum); + + if (velocity != last_velocity_) { + last_velocity_ = velocity; + if (middle_click_mode_ == kMiddleClickInitial) + middle_click_mode_ = kMiddleClickHolding; + view->SetCursor(MiddleClickAutoscrollCursor(velocity)); + page_->GetChromeClient().AutoscrollFling(velocity, frame); } } +void AutoscrollController::HandleMouseReleaseForMiddleClickAutoscroll( + LocalFrame* frame, + bool is_middle_button) { + DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()); + if (!MiddleClickAutoscrollInProgress()) + return; + + if (!frame->IsMainFrame()) + return; + + if (middle_click_mode_ == kMiddleClickInitial && is_middle_button) + middle_click_mode_ = kMiddleClickToggled; + else if (middle_click_mode_ == kMiddleClickHolding) + StopMiddleClickAutoscroll(frame); +} + +void AutoscrollController::StopMiddleClickAutoscroll(LocalFrame* frame) { + if (!MiddleClickAutoscrollInProgress()) + return; + + page_->GetChromeClient().AutoscrollEnd(frame); + autoscroll_type_ = kNoAutoscroll; + frame->LocalFrameRoot().GetEventHandler().ScheduleCursorUpdate(); +} + bool AutoscrollController::MiddleClickAutoscrollInProgress() const { - return autoscroll_type_ == kAutoscrollForMiddleClickCanStop || - autoscroll_type_ == kAutoscrollForMiddleClick; + return autoscroll_type_ == kAutoscrollForMiddleClick; } void AutoscrollController::StartMiddleClickAutoscroll( - LayoutBox* scrollable, - const IntPoint& last_known_mouse_position) { + LocalFrame* frame, + const FloatPoint& position, + const FloatPoint& position_global) { DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()); // We don't want to trigger the autoscroll or the middleClickAutoscroll if // it's already active. @@ -238,69 +283,23 @@ return; autoscroll_type_ = kAutoscrollForMiddleClick; - autoscroll_layout_object_ = scrollable; - middle_click_autoscroll_start_pos_ = last_known_mouse_position; - did_latch_for_middle_click_autoscroll_ = false; + middle_click_mode_ = kMiddleClickInitial; + middle_click_autoscroll_start_pos_global_ = position_global; - UseCounter::Count(autoscroll_layout_object_->GetFrame(), - WebFeature::kMiddleClickAutoscrollStart); - StartAutoscroll(); -} + UseCounter::Count(frame, WebFeature::kMiddleClickAutoscrollStart); -static inline int AdjustedScrollDelta(int beginning_delta) { - // This implemention matches Firefox's. - // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856. - const int kSpeedReducer = 12; - - int adjusted_delta = beginning_delta / kSpeedReducer; - if (adjusted_delta > 1) { - adjusted_delta = - static_cast<int>(adjusted_delta * - sqrt(static_cast<double>(adjusted_delta))) - - 1; - } else if (adjusted_delta < -1) { - adjusted_delta = - static_cast<int>(adjusted_delta * - sqrt(static_cast<double>(-adjusted_delta))) + - 1; - } - - return adjusted_delta; -} - -static inline IntSize AdjustedScrollDelta(const IntSize& delta) { - return IntSize(AdjustedScrollDelta(delta.Width()), - AdjustedScrollDelta(delta.Height())); -} - -FloatSize AutoscrollController::CalculateAutoscrollDelta() { - LocalFrame* frame = autoscroll_layout_object_->GetFrame(); - if (!frame) - return FloatSize(); - - IntPoint last_known_mouse_position = - frame->GetEventHandler().LastKnownMousePosition(); - - // We need to check if the last known mouse position is out of the window. - // When the mouse is out of the window, the position is incoherent - static IntPoint previous_mouse_position; - if (last_known_mouse_position.X() < 0 || last_known_mouse_position.Y() < 0) - last_known_mouse_position = previous_mouse_position; - else - previous_mouse_position = last_known_mouse_position; - - IntSize delta = - last_known_mouse_position - middle_click_autoscroll_start_pos_; - - // at the center we let the space for the icon. - if (abs(delta.Width()) <= kNoMiddleClickAutoscrollRadius) - delta.SetWidth(0); - if (abs(delta.Height()) <= kNoMiddleClickAutoscrollRadius) - delta.SetHeight(0); - return FloatSize(AdjustedScrollDelta(delta)); + last_velocity_ = FloatSize(); + if (LocalFrameView* view = frame->View()) + view->SetCursor(MiddleClickAutoscrollCursor(last_velocity_)); + page_->GetChromeClient().AutoscrollStart( + position.ScaledBy(1 / frame->DevicePixelRatio()), frame); } void AutoscrollController::Animate(double) { + // Middle-click autoscroll isn't handled on the main thread. + if (MiddleClickAutoscrollInProgress()) + return; + if (!autoscroll_layout_object_ || !autoscroll_layout_object_->GetFrame()) { StopAutoscroll(); return; @@ -313,6 +312,7 @@ IntPoint selection_point = event_handler.LastKnownMousePosition() + offset; switch (autoscroll_type_) { case kAutoscrollForDragAndDrop: + ScheduleMainThreadAnimation(); if ((TimeTicks::Now() - drag_and_drop_autoscroll_start_time_) > kAutoscrollDelay) autoscroll_layout_object_->Autoscroll( @@ -324,98 +324,18 @@ return; } event_handler.UpdateSelectionForMouseDrag(); + ScheduleMainThreadAnimation(); autoscroll_layout_object_->Autoscroll(selection_point); break; case kNoAutoscroll: - break; - case kAutoscrollForMiddleClickCanStop: case kAutoscrollForMiddleClick: - DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()); - if (!MiddleClickAutoscrollInProgress()) { - StopAutoscroll(); - return; - } - if (LocalFrameView* view = autoscroll_layout_object_->GetFrame()->View()) - UpdateMiddleClickAutoscrollState( - view, event_handler.LastKnownMousePosition()); - FloatSize delta = CalculateAutoscrollDelta(); - if (delta.IsZero()) - break; - ScrollResult result = - autoscroll_layout_object_->Scroll(kScrollByPixel, delta); - LayoutObject* layout_object = autoscroll_layout_object_; - while (!did_latch_for_middle_click_autoscroll_ && !result.DidScroll()) { - if (layout_object->GetNode() && - layout_object->GetNode()->IsDocumentNode()) { - Element* owner = ToDocument(layout_object->GetNode())->LocalOwner(); - layout_object = owner ? owner->GetLayoutObject() : nullptr; - } else { - layout_object = layout_object->Parent(); - } - if (!layout_object) { - break; - } - if (layout_object && layout_object->IsBox() && - ToLayoutBox(layout_object)->CanBeScrolledAndHasScrollableArea()) - result = ToLayoutBox(layout_object)->Scroll(kScrollByPixel, delta); - } - if (result.DidScroll()) { - did_latch_for_middle_click_autoscroll_ = true; - autoscroll_layout_object_ = ToLayoutBox(layout_object); - } break; } - if (autoscroll_type_ != kNoAutoscroll && autoscroll_layout_object_) { - page_->GetChromeClient().ScheduleAnimation( - autoscroll_layout_object_->GetFrame()->View()); - } } -void AutoscrollController::StartAutoscroll() { +void AutoscrollController::ScheduleMainThreadAnimation() { page_->GetChromeClient().ScheduleAnimation( autoscroll_layout_object_->GetFrame()->View()); } -void AutoscrollController::UpdateMiddleClickAutoscrollState( - LocalFrameView* view, - const IntPoint& last_known_mouse_position) { - DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()); - // At the original click location we draw a 4 arrowed icon. Over this icon - // there won't be any scroll, So don't change the cursor over this area. - bool east = middle_click_autoscroll_start_pos_.X() < - (last_known_mouse_position.X() - kNoMiddleClickAutoscrollRadius); - bool west = middle_click_autoscroll_start_pos_.X() > - (last_known_mouse_position.X() + kNoMiddleClickAutoscrollRadius); - bool north = middle_click_autoscroll_start_pos_.Y() > - (last_known_mouse_position.Y() + kNoMiddleClickAutoscrollRadius); - bool south = middle_click_autoscroll_start_pos_.Y() < - (last_known_mouse_position.Y() - kNoMiddleClickAutoscrollRadius); - - if (autoscroll_type_ == kAutoscrollForMiddleClick && - (east || west || north || south)) - autoscroll_type_ = kAutoscrollForMiddleClickCanStop; - - if (north) { - if (east) - view->SetCursor(NorthEastPanningCursor()); - else if (west) - view->SetCursor(NorthWestPanningCursor()); - else - view->SetCursor(NorthPanningCursor()); - } else if (south) { - if (east) - view->SetCursor(SouthEastPanningCursor()); - else if (west) - view->SetCursor(SouthWestPanningCursor()); - else - view->SetCursor(SouthPanningCursor()); - } else if (east) { - view->SetCursor(EastPanningCursor()); - } else if (west) { - view->SetCursor(WestPanningCursor()); - } else { - view->SetCursor(MiddlePanningCursor()); - } -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/AutoscrollController.h b/third_party/WebKit/Source/core/page/AutoscrollController.h index b2e5093..d4a34b6 100644 --- a/third_party/WebKit/Source/core/page/AutoscrollController.h +++ b/third_party/WebKit/Source/core/page/AutoscrollController.h
@@ -27,6 +27,7 @@ #define AutoscrollController_h #include "core/CoreExport.h" +#include "platform/geometry/FloatPoint.h" #include "platform/geometry/FloatSize.h" #include "platform/geometry/IntPoint.h" #include "platform/heap/Handle.h" @@ -35,21 +36,30 @@ namespace blink { class LocalFrame; -class LocalFrameView; class Node; class Page; class LayoutBox; class LayoutObject; -class WebMouseEvent; enum AutoscrollType { kNoAutoscroll, kAutoscrollForDragAndDrop, kAutoscrollForSelection, - kAutoscrollForMiddleClickCanStop, kAutoscrollForMiddleClick, }; +enum MiddleClickMode { + // Middle button was just pressed but was neither released nor moved out of + // the deadzone yet. + kMiddleClickInitial, + // Mouse was moved out of the deadzone while still holding middle mouse + // button. In this mode, we'll stop autoscrolling when it's released. + kMiddleClickHolding, + // Middle button was released while still in the deadzone. In this mode, + // we'll stop autoscrolling when any button is clicked. + kMiddleClickToggled, +}; + // AutscrollController handels autoscroll and middle click autoscroll for // EventHandler. class CORE_EXPORT AutoscrollController final @@ -58,12 +68,10 @@ static AutoscrollController* Create(Page&); DECLARE_TRACE(); - static const int kNoMiddleClickAutoscrollRadius = 15; - + // Selection and drag-and-drop autoscroll. void Animate(double monotonic_frame_begin_time); - bool AutoscrollInProgress() const; + bool SelectionAutoscrollInProgress() const; bool AutoscrollInProgress(const LayoutBox*) const; - bool MiddleClickAutoscrollInProgress() const; void StartAutoscrollForSelection(LayoutObject*); void StopAutoscroll(); void StopAutoscrollIfNeeded(LayoutObject*); @@ -71,28 +79,37 @@ void UpdateDragAndDrop(Node* target_node, const IntPoint& event_position, TimeTicks event_time); + + // Middle-click autoscroll. + void StartMiddleClickAutoscroll(LocalFrame*, + const FloatPoint& position, + const FloatPoint& position_global); + void HandleMouseMoveForMiddleClickAutoscroll( + LocalFrame*, + const FloatPoint& position_global, + bool is_middle_button); void HandleMouseReleaseForMiddleClickAutoscroll(LocalFrame*, - const WebMouseEvent&); - void StartMiddleClickAutoscroll(LayoutBox*, const IntPoint&); + bool is_middle_button); + void StopMiddleClickAutoscroll(LocalFrame*); + bool MiddleClickAutoscrollInProgress() const; private: explicit AutoscrollController(Page&); - void StartAutoscroll(); - - void UpdateMiddleClickAutoscrollState( - LocalFrameView*, - const IntPoint& last_known_mouse_position); - FloatSize CalculateAutoscrollDelta(); - Member<Page> page_; - LayoutBox* autoscroll_layout_object_; - LayoutBox* pressed_layout_object_; - AutoscrollType autoscroll_type_; + AutoscrollType autoscroll_type_ = kNoAutoscroll; + + // Selection and drag-and-drop autoscroll. + void ScheduleMainThreadAnimation(); + LayoutBox* autoscroll_layout_object_ = nullptr; + LayoutBox* pressed_layout_object_ = nullptr; IntPoint drag_and_drop_autoscroll_reference_position_; TimeTicks drag_and_drop_autoscroll_start_time_; - IntPoint middle_click_autoscroll_start_pos_; - bool did_latch_for_middle_click_autoscroll_; + + // Middle-click autoscroll. + FloatPoint middle_click_autoscroll_start_pos_global_; + FloatSize last_velocity_; + MiddleClickMode middle_click_mode_ = kMiddleClickInitial; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 27975db8..1b1ecbd0 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -177,6 +177,11 @@ // End methods used by PlatformChromeClient. virtual void SetCursorOverridden(bool) = 0; + + virtual void AutoscrollStart(WebFloatPoint position, LocalFrame*) {} + virtual void AutoscrollFling(WebFloatSize velocity, LocalFrame*) {} + virtual void AutoscrollEnd(LocalFrame*) {} + virtual Cursor LastSetCursorForTesting() const = 0; Node* LastSetTooltipNodeForTesting() const { return last_mouse_over_node_.Get();
diff --git a/third_party/WebKit/Source/core/paint/LinkHighlightImplTest.cpp b/third_party/WebKit/Source/core/paint/LinkHighlightImplTest.cpp index e48fcad..ad30157 100644 --- a/third_party/WebKit/Source/core/paint/LinkHighlightImplTest.cpp +++ b/third_party/WebKit/Source/core/paint/LinkHighlightImplTest.cpp
@@ -78,7 +78,7 @@ TEST(LinkHighlightImplTest, verifyWebViewImplIntegration) { const std::string url = RegisterMockedURLLoad(); FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad(url, true); + WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad(url); int page_width = 640; int page_height = 480; web_view_impl->Resize(WebSize(page_width, page_height)); @@ -151,7 +151,7 @@ const std::string url = RegisterMockedURLLoad(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - url, true, 0, CompositingWebViewClient()); + url, nullptr, CompositingWebViewClient()); int page_width = 640; int page_height = 480; @@ -189,13 +189,12 @@ // A lifetime test: delete LayerTreeView while running LinkHighlights. TEST(LinkHighlightImplTest, resetLayerTreeView) { - std::unique_ptr<FakeCompositingWebViewClient> web_view_client = - WTF::MakeUnique<FakeCompositingWebViewClient>(); + FakeCompositingWebViewClient web_view_client; const std::string url = RegisterMockedURLLoad(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = - web_view_helper.InitializeAndLoad(url, true, 0, web_view_client.get()); + web_view_helper.InitializeAndLoad(url, nullptr, &web_view_client); int page_width = 640; int page_height = 480; @@ -235,7 +234,7 @@ const std::string url = RegisterMockedURLLoad(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - url, true, 0, CompositingWebViewClient()); + url, nullptr, CompositingWebViewClient()); int page_width = 640; int page_height = 480;
diff --git a/third_party/WebKit/Source/core/style/BUILD.gn b/third_party/WebKit/Source/core/style/BUILD.gn index f8f0ca9b..94579e8f 100644 --- a/third_party/WebKit/Source/core/style/BUILD.gn +++ b/third_party/WebKit/Source/core/style/BUILD.gn
@@ -58,6 +58,7 @@ "QuadLengthValue.h", "QuotesData.cpp", "QuotesData.h", + "ScrollSnap.h", "ShadowData.cpp", "ShadowData.h", "ShadowList.cpp", @@ -91,8 +92,6 @@ "StyleRay.cpp", "StyleRay.h", "StyleReflection.h", - "StyleScrollSnapData.cpp", - "StyleScrollSnapData.h", "StyleSelfAlignmentData.h", "TextSizeAdjust.h", ]
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index f8e1496..fd04bfa 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -123,7 +123,6 @@ : ComputedStyleBase(), RefCounted<ComputedStyle>() { // TODO(shend): Generate these. rare_non_inherited_data_.Access()->grid_data_.Init(); - rare_non_inherited_data_.Access()->scroll_snap_data_.Init(); svg_style_.Init(); }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index f1016776..e985a32 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1313,10 +1313,11 @@ // scroll-snap-type static ScrollSnapType InitialScrollSnapType() { return ScrollSnapType(); } ScrollSnapType GetScrollSnapType() const { - return rare_non_inherited_data_->scroll_snap_data_->type_; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_type_; } void SetScrollSnapType(const ScrollSnapType& b) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, type_, b); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_type_, b); } // Scroll Padding properties @@ -1324,38 +1325,38 @@ // scroll-padding-top const Length& ScrollPaddingTop() const { - return rare_non_inherited_data_->scroll_snap_data_->padding_.top; + return rare_non_inherited_data_->scroll_snap_data_->scroll_padding_.top; } void SetScrollPaddingTop(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, padding_.top, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_padding_.top, v); } // scroll-padding-bottom const Length& ScrollPaddingBottom() const { - return rare_non_inherited_data_->scroll_snap_data_->padding_.bottom; + return rare_non_inherited_data_->scroll_snap_data_->scroll_padding_.bottom; } void SetScrollPaddingBottom(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, padding_.bottom, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_padding_.bottom, v); } // scroll-padding-left const Length& ScrollPaddingLeft() const { - return rare_non_inherited_data_->scroll_snap_data_->padding_.left; + return rare_non_inherited_data_->scroll_snap_data_->scroll_padding_.left; } void SetScrollPaddingLeft(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, padding_.left, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_padding_.left, v); } // scroll-padding-right const Length& ScrollPaddingRight() const { - return rare_non_inherited_data_->scroll_snap_data_->padding_.right; + return rare_non_inherited_data_->scroll_snap_data_->scroll_padding_.right; } void SetScrollPaddingRight(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, padding_.right, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_padding_.right, v); } // scroll-padding-block-start @@ -1409,37 +1410,41 @@ // scroll-snap-margin-top const Length& ScrollSnapMarginTop() const { - return rare_non_inherited_data_->scroll_snap_data_->margin_.top; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_margin_.top; } void SetScrollSnapMarginTop(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, margin_.top, v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_margin_.top, v); } // scroll-snap-margin-bottom const Length& ScrollSnapMarginBottom() const { - return rare_non_inherited_data_->scroll_snap_data_->margin_.bottom; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_margin_ + .bottom; } void SetScrollSnapMarginBottom(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, margin_.bottom, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_margin_.bottom, v); } // scroll-snap-margin-left const Length& ScrollSnapMarginLeft() const { - return rare_non_inherited_data_->scroll_snap_data_->margin_.left; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_margin_ + .left; } void SetScrollSnapMarginLeft(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, margin_.left, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_margin_.left, v); } // scroll-snap-margin-right const Length& ScrollSnapMarginRight() const { - return rare_non_inherited_data_->scroll_snap_data_->margin_.right; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_margin_ + .right; } void SetScrollSnapMarginRight(const Length& v) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, margin_.right, - v); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_margin_.right, v); } // scroll-snap-margin-block-start @@ -1493,10 +1498,11 @@ // scroll-snap-align static ScrollSnapAlign InitialScrollSnapAlign() { return ScrollSnapAlign(); } ScrollSnapAlign GetScrollSnapAlign() const { - return rare_non_inherited_data_->scroll_snap_data_->align_; + return rare_non_inherited_data_->scroll_snap_data_->scroll_snap_align_; } void SetScrollSnapAlign(const ScrollSnapAlign& b) { - SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, align_, b); + SET_NESTED_VAR(rare_non_inherited_data_, scroll_snap_data_, + scroll_snap_align_, b); } // shape-image-threshold (aka -webkit-shape-image-threshold)
diff --git a/third_party/WebKit/Source/core/style/ScrollSnap.h b/third_party/WebKit/Source/core/style/ScrollSnap.h new file mode 100644 index 0000000..24afd8b --- /dev/null +++ b/third_party/WebKit/Source/core/style/ScrollSnap.h
@@ -0,0 +1,66 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ScrollSnap_h +#define ScrollSnap_h + +#include "core/style/ComputedStyleConstants.h" +#include "core/style/QuadLengthValue.h" + +namespace blink { + +using ScrollPadding = QuadLengthValue; +using ScrollSnapMargin = QuadLengthValue; + +struct ScrollSnapType { + DISALLOW_NEW(); + + ScrollSnapType() + : is_none(true), + axis(kSnapAxisBoth), + strictness(kSnapStrictnessProximity) {} + + ScrollSnapType(const ScrollSnapType& other) + : is_none(other.is_none), + axis(other.axis), + strictness(other.strictness) {} + + bool operator==(const ScrollSnapType& other) const { + return is_none == other.is_none && axis == other.axis && + strictness == other.strictness; + } + + bool operator!=(const ScrollSnapType& other) const { + return !(*this == other); + } + + bool is_none; + SnapAxis axis; + SnapStrictness strictness; +}; + +struct ScrollSnapAlign { + DISALLOW_NEW(); + + ScrollSnapAlign() + : alignmentX(kSnapAlignmentNone), alignmentY(kSnapAlignmentNone) {} + + ScrollSnapAlign(const ScrollSnapAlign& other) + : alignmentX(other.alignmentX), alignmentY(other.alignmentY) {} + + bool operator==(const ScrollSnapAlign& other) const { + return alignmentX == other.alignmentX && alignmentY == other.alignmentY; + } + + bool operator!=(const ScrollSnapAlign& other) const { + return !(*this == other); + } + + SnapAlignment alignmentX; + SnapAlignment alignmentY; +}; + +} // namespace blink + +#endif // ScrollSnap_h
diff --git a/third_party/WebKit/Source/core/style/StyleScrollSnapData.cpp b/third_party/WebKit/Source/core/style/StyleScrollSnapData.cpp deleted file mode 100644 index e6841a2..0000000 --- a/third_party/WebKit/Source/core/style/StyleScrollSnapData.cpp +++ /dev/null
@@ -1,49 +0,0 @@ -/* - * Copyright (C) 2014 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core/style/StyleScrollSnapData.h" - -#include "core/style/ComputedStyle.h" - -namespace blink { - -StyleScrollSnapData::StyleScrollSnapData() - : type_(ComputedStyle::InitialScrollSnapType()), - align_(ComputedStyle::InitialScrollSnapAlign()), - padding_(ComputedStyle::InitialScrollPadding()), - margin_(ComputedStyle::InitialScrollSnapMargin()) {} - -StyleScrollSnapData::StyleScrollSnapData(const StyleScrollSnapData& other) - : type_(other.type_), - align_(other.align_), - padding_(other.padding_), - margin_(other.margin_) {} - -bool operator==(const StyleScrollSnapData& a, const StyleScrollSnapData& b) { - return a.type_ == b.type_ && a.align_ == b.align_ && - a.padding_ == b.padding_ && a.margin_ == b.margin_; -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/style/StyleScrollSnapData.h b/third_party/WebKit/Source/core/style/StyleScrollSnapData.h deleted file mode 100644 index ea02b97..0000000 --- a/third_party/WebKit/Source/core/style/StyleScrollSnapData.h +++ /dev/null
@@ -1,116 +0,0 @@ -/* - * Copyright (C) 2014 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StyleScrollSnapData_h -#define StyleScrollSnapData_h - -#include "core/style/ComputedStyleConstants.h" -#include "core/style/QuadLengthValue.h" -#include "platform/LengthPoint.h" -#include "platform/wtf/Allocator.h" -#include "platform/wtf/RefCounted.h" -#include "platform/wtf/Vector.h" - -namespace blink { - -using ScrollPadding = QuadLengthValue; -using ScrollSnapMargin = QuadLengthValue; - -struct ScrollSnapType { - DISALLOW_NEW(); - - ScrollSnapType() - : is_none(true), - axis(kSnapAxisBoth), - strictness(kSnapStrictnessProximity) {} - - ScrollSnapType(const ScrollSnapType& other) - : is_none(other.is_none), - axis(other.axis), - strictness(other.strictness) {} - - bool operator==(const ScrollSnapType& other) const { - return is_none == other.is_none && axis == other.axis && - strictness == other.strictness; - } - - bool operator!=(const ScrollSnapType& other) const { - return !(*this == other); - } - - bool is_none; - SnapAxis axis; - SnapStrictness strictness; -}; - -struct ScrollSnapAlign { - DISALLOW_NEW(); - - ScrollSnapAlign() - : alignmentX(kSnapAlignmentNone), alignmentY(kSnapAlignmentNone) {} - - ScrollSnapAlign(const ScrollSnapAlign& other) - : alignmentX(other.alignmentX), alignmentY(other.alignmentY) {} - - bool operator==(const ScrollSnapAlign& other) const { - return alignmentX == other.alignmentX && alignmentY == other.alignmentY; - } - - bool operator!=(const ScrollSnapAlign& other) const { - return !(*this == other); - } - - SnapAlignment alignmentX; - SnapAlignment alignmentY; -}; - -class StyleScrollSnapData : public RefCounted<StyleScrollSnapData> { - public: - static PassRefPtr<StyleScrollSnapData> Create() { - return AdoptRef(new StyleScrollSnapData); - } - PassRefPtr<StyleScrollSnapData> Copy() { - return AdoptRef(new StyleScrollSnapData(*this)); - } - - ScrollSnapType type_; - ScrollSnapAlign align_; - ScrollPadding padding_; - ScrollSnapMargin margin_; - - private: - StyleScrollSnapData(); - StyleScrollSnapData(const StyleScrollSnapData& other); -}; - -bool operator==(const StyleScrollSnapData&, const StyleScrollSnapData&); -inline bool operator!=(const StyleScrollSnapData& a, - const StyleScrollSnapData& b) { - return !(a == b); -} - -} // namespace blink - -#endif // StyleScrollSnapData_h
diff --git a/third_party/WebKit/Source/core/testing/sim/SimTest.cpp b/third_party/WebKit/Source/core/testing/sim/SimTest.cpp index 2b8cc348..a4e86fb3 100644 --- a/third_party/WebKit/Source/core/testing/sim/SimTest.cpp +++ b/third_party/WebKit/Source/core/testing/sim/SimTest.cpp
@@ -40,7 +40,7 @@ void SimTest::SetUp() { Test::SetUp(); - web_view_helper_.Initialize(true, &web_frame_client_, &web_view_client_); + web_view_helper_.Initialize(&web_frame_client_, &web_view_client_); compositor_.SetWebView(WebView()); page_.SetPage(WebView().GetPage()); }
diff --git a/third_party/WebKit/Source/core/testing/sim/SimWebViewClient.cpp b/third_party/WebKit/Source/core/testing/sim/SimWebViewClient.cpp index 471aa38..ccf3788 100644 --- a/third_party/WebKit/Source/core/testing/sim/SimWebViewClient.cpp +++ b/third_party/WebKit/Source/core/testing/sim/SimWebViewClient.cpp
@@ -36,7 +36,7 @@ const WebString& name, WebNavigationPolicy, bool) { - return web_view_helper_.InitializeWithOpener(opener, true); + return web_view_helper_.InitializeWithOpener(opener); } } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn index 8ed7791..16e167a20 100644 --- a/third_party/WebKit/Source/devtools/BUILD.gn +++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -15,7 +15,7 @@ "front_end/accessibility/ARIAAttributesView.js", "front_end/accessibility/ARIAConfig.js", "front_end/accessibility/ARIAMetadata.js", - "front_end/accessibility/AXTreePane.js", + "front_end/accessibility/AXBreadcrumbsPane.js", "front_end/accessibility/module.json", "front_end/animation/AnimationGroupPreviewUI.js", "front_end/animation/AnimationModel.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js new file mode 100644 index 0000000..0f1d0ec4 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AXBreadcrumbsPane.js
@@ -0,0 +1,392 @@ +// 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. + +Accessibility.AXBreadcrumbsPane = class extends Accessibility.AccessibilitySubPane { + /** + * @param {!Accessibility.AccessibilitySidebarView} axSidebarView + */ + constructor(axSidebarView) { + super(Common.UIString('Accessibility Tree')); + + this.element.classList.add('ax-subpane'); + + this._axSidebarView = axSidebarView; + + /** @type {?Accessibility.AXBreadcrumb} */ + this._preselectedBreadcrumb = null; + + this._selectedByUser = true; + + this._hoveredBreadcrumb = null; + this._rootElement = this.element.createChild('div', 'ax-breadcrumbs'); + + this._rootElement.addEventListener('keydown', this._onKeyDown.bind(this), true); + this._rootElement.addEventListener('mousemove', this._onMouseMove.bind(this), false); + this._rootElement.addEventListener('mouseleave', this._onMouseLeave.bind(this), false); + this._rootElement.addEventListener('click', this._onClick.bind(this), false); + } + + /** + * @param {?Accessibility.AccessibilityNode} axNode + * @override + */ + setAXNode(axNode) { + super.setAXNode(axNode); + + this._rootElement.removeChildren(); + + if (!axNode) { + this._selectedByUser = false; + return; + } + + var ancestorChain = []; + var ancestor = axNode; + while (ancestor) { + ancestorChain.push(ancestor); + ancestor = ancestor.parentNode(); + } + ancestorChain.reverse(); + + var depth = 0; + var breadcrumb = null; + for (ancestor of ancestorChain) { + breadcrumb = new Accessibility.AXBreadcrumb(ancestor, depth, (ancestor === axNode)); + if (ancestor.children().length) + breadcrumb.element().classList.add('parent'); + this._rootElement.appendChild(breadcrumb.element()); + depth++; + } + + var inspectedNodeBreadcrumb = breadcrumb; + inspectedNodeBreadcrumb.setPreselected(true, this._selectedByUser); + + this._setPreselectedBreadcrumb(inspectedNodeBreadcrumb); + + for (var child of axNode.children()) { + var childBreadcrumb = new Accessibility.AXBreadcrumb(child, depth, false); + this._rootElement.appendChild(childBreadcrumb.element()); + } + + this._selectedByUser = false; + } + + /** + * @override + */ + wasShown() { + this._selectedByUser = true; + } + + /** + * @override + */ + willHide() { + this._setPreselectedBreadcrumb(null); + } + + /** + * @param {!Event} event + */ + _onKeyDown(event) { + if (!this._preselectedBreadcrumb) + return; + if (!event.path.some(element => element === this._preselectedBreadcrumb.element())) + return; + if (event.shiftKey || event.metaKey || event.ctrlKey) + return; + + var handled = false; + if ((event.key === 'ArrowUp' || event.key === 'ArrowLeft') && !event.altKey) + handled = this._preselectPrevious(); + else if ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && !event.altKey) + handled = this._preselectNext(); + else if (isEnterKey(event)) + handled = this._inspectDOMNode(this._preselectedBreadcrumb.axNode()); + + if (handled) + event.consume(true); + } + + /** + * @return {boolean} + */ + _preselectPrevious() { + var previousElement = this._preselectedBreadcrumb.element().previousSibling; + if (!previousElement) + return false; + this._selectedByUser = true; + this._setPreselectedBreadcrumb(previousElement.breadcrumb); + return true; + } + + /** + * @return {boolean} + */ + _preselectNext() { + var nextElement = this._preselectedBreadcrumb.element().nextSibling; + if (!nextElement) + return false; + this._selectedByUser = true; + this._setPreselectedBreadcrumb(nextElement.breadcrumb); + return true; + } + + /** + * @param {?Accessibility.AXBreadcrumb} breadcrumb + */ + _setPreselectedBreadcrumb(breadcrumb) { + if (breadcrumb === this._preselectedBreadcrumb) + return; + if (this._preselectedBreadcrumb) + this._preselectedBreadcrumb.setPreselected(false, this._selectedByUser); + this._preselectedBreadcrumb = breadcrumb; + if (this._preselectedBreadcrumb) + this._preselectedBreadcrumb.setPreselected(true, this._selectedByUser); + else if (this._selectedByUser) + SDK.OverlayModel.hideDOMNodeHighlight(); + } + + /** + * @param {!Event} event + */ + _onMouseLeave(event) { + this._setHoveredBreadcrumb(null); + } + + /** + * @param {!Event} event + */ + _onMouseMove(event) { + var breadcrumbElement = event.target.enclosingNodeOrSelfWithClass('ax-node'); + if (!breadcrumbElement) { + this._setHoveredBreadcrumb(null); + return; + } + var breadcrumb = breadcrumbElement.breadcrumb; + if (breadcrumb.preselected() || breadcrumb.inspected() || !breadcrumb.isDOMNode()) + return; + this._setHoveredBreadcrumb(breadcrumb); + } + + /** + * @param {!Event} event + */ + _onClick(event) { + var breadcrumbElement = event.target.enclosingNodeOrSelfWithClass('ax-node'); + if (!breadcrumbElement) { + this._setHoveredBreadcrumb(null); + return; + } + var breadcrumb = breadcrumbElement.breadcrumb; + if (breadcrumb.inspected()) { + // If the user is clicking the inspected breadcrumb, they probably want to + // focus it. + breadcrumb.element().focus(); + return; + } + if (!breadcrumb.isDOMNode()) + return; + this._inspectDOMNode(breadcrumb.axNode()); + } + + /** + * @param {?Accessibility.AXBreadcrumb} breadcrumb + */ + _setHoveredBreadcrumb(breadcrumb) { + if (breadcrumb === this._hoveredBreadcrumb) + return; + + if (this._hoveredBreadcrumb) + this._hoveredBreadcrumb.setHovered(false); + + if (breadcrumb) { + breadcrumb.setHovered(true); + } else if (this.node()) { + // Highlight and scroll into view the currently inspected node. + this.node().domModel().overlayModel().nodeHighlightRequested(this.node().id); + } + + this._hoveredBreadcrumb = breadcrumb; + } + + /** + * @param {!Accessibility.AccessibilityNode} axNode + * @return {boolean} + */ + _inspectDOMNode(axNode) { + if (!axNode.isDOMNode()) + return false; + + this._selectedByUser = true; + + axNode.deferredDOMNode().resolve(domNode => { + var inspectedDOMNode = UI.context.flavor(SDK.DOMNode); + // Special case the root accessibility node: set the node for the + // accessibility panel, not the Elements tree, as it maps to the Document + // node which is not shown in the DOM panel, causing the first child to be + // inspected instead. + if (axNode.parentNode() && domNode !== inspectedDOMNode) + Common.Revealer.reveal(domNode, true /* omitFocus */); + else + this._axSidebarView.setNode(domNode); + }); + + return true; + } +}; + +Accessibility.AXBreadcrumb = class { + /** + * @param {!Accessibility.AccessibilityNode} axNode + * @param {number} depth + * @param {boolean} inspected + */ + constructor(axNode, depth, inspected) { + /** @type {!Accessibility.AccessibilityNode} */ + this._axNode = axNode; + + this._element = createElementWithClass('div', 'ax-node'); + this._element.breadcrumb = this; + + this._selectionElement = createElementWithClass('div', 'selection fill'); + this._element.appendChild(this._selectionElement); + + this._nodeWrapper = createElementWithClass('span', 'wrapper'); + this._element.appendChild(this._nodeWrapper); + + this._hovered = false; + this._preselected = false; + + this._inspected = inspected; + this.element().classList.toggle('inspected', inspected); + + this._element.style.paddingLeft = (16 * depth + 4) + 'px'; + + if (this._axNode.ignored()) { + this._appendIgnoredNodeElement(); + } else { + this._appendRoleElement(this._axNode.role()); + if (this._axNode.name() && this._axNode.name().value) { + this._nodeWrapper.createChild('span', 'separator').textContent = '\u00A0'; + this._appendNameElement(/** @type {string} */ (this._axNode.name().value)); + } + } + + if (this._axNode.hasOnlyUnloadedChildren()) + this._element.classList.add('children-unloaded'); + + if (!this._axNode.isDOMNode()) + this._element.classList.add('no-dom-node'); + } + + /** + * @return {!Element} + */ + element() { + return this._element; + } + + /** + * @return {boolean} + */ + preselected() { + return this._preselected; + } + + /** + * @param {boolean} preselected + * @param {boolean} selectedByUser + */ + setPreselected(preselected, selectedByUser) { + if (this._preselected === preselected) + return; + this._preselected = preselected; + this.element().classList.toggle('preselected', preselected); + if (preselected) + this.element().setAttribute('tabIndex', 0); + else + this.element().removeAttribute('tabIndex'); + if (this._preselected) { + if (selectedByUser) + this.element().focus(); + if (!this._inspected) + this._axNode.highlightDOMNode(); + else + SDK.OverlayModel.hideDOMNodeHighlight(); + } + } + + /** + * @param {boolean} hovered + */ + setHovered(hovered) { + if (this._hovered === hovered) + return; + this._hovered = hovered; + this.element().classList.toggle('hovered', hovered); + if (this._hovered) { + this.element().classList.toggle('hovered', true); + this._axNode.highlightDOMNode(); + } + } + + /** + * @return {!Accessibility.AccessibilityNode} + */ + axNode() { + return this._axNode; + } + + /** + * @return {boolean} + */ + inspected() { + return this._inspected; + } + + /** + * @return {boolean} + */ + isDOMNode() { + return this._axNode.isDOMNode(); + } + + /** + * @param {string} name + */ + _appendNameElement(name) { + var nameElement = createElement('span'); + nameElement.textContent = '"' + name + '"'; + nameElement.classList.add('ax-readable-string'); + this._nodeWrapper.appendChild(nameElement); + } + + /** + * @param {?Protocol.Accessibility.AXValue} role + */ + _appendRoleElement(role) { + if (!role) + return; + + var roleElement = createElementWithClass('span', 'monospace'); + roleElement.classList.add(Accessibility.AXBreadcrumb.RoleStyles[role.type]); + roleElement.setTextContentTruncatedIfNeeded(role.value || ''); + + this._nodeWrapper.appendChild(roleElement); + } + + _appendIgnoredNodeElement() { + var ignoredNodeElement = createElementWithClass('span', 'monospace'); + ignoredNodeElement.textContent = Common.UIString('Ignored'); + ignoredNodeElement.classList.add('ax-breadcrumbs-ignored-node'); + this._nodeWrapper.appendChild(ignoredNodeElement); + } +}; + +/** @type {!Object<string, string>} */ +Accessibility.AXBreadcrumb.RoleStyles = { + internalRole: 'ax-internal-role', + role: 'ax-role', +};
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js deleted file mode 100644 index 884dd30..0000000 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AXTreePane.js +++ /dev/null
@@ -1,515 +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. -/** - * @unrestricted - */ -Accessibility.AXTreePane = class extends Accessibility.AccessibilitySubPane { - /** - * @param {!Accessibility.AccessibilitySidebarView} axSidebarView - */ - constructor(axSidebarView) { - super(Common.UIString('Accessibility Tree')); - - this._axSidebarView = axSidebarView; - this._treeOutline = this.createTreeOutline(); - this._treeOutline.contentElement.classList.add('ax-tree'); - this._treeOutline.setPaddingSize(12); - this._treeOutline.element.addEventListener('keydown', this._onKeyDown.bind(this), true); - this._treeOutline.element.addEventListener('mouseleave', this._onMouseLeave.bind(this), false); - - this.element.classList.add('accessibility-computed'); - - this._preselectedTreeElement = null; - this._hoveredTreeElement = null; - } - - /** - * @param {?Accessibility.AccessibilityNode} axNode - * @override - */ - setAXNode(axNode) { - this._axNode = axNode; - - var treeOutline = this._treeOutline; - treeOutline.removeChildren(); - - // TODO(aboxhall): show no node UI - if (!axNode) - return; - - treeOutline.element.classList.remove('hidden'); - var previousTreeElement = treeOutline.rootElement(); - var inspectedNodeTreeElement = new Accessibility.AXNodeTreeElement(axNode, this); - inspectedNodeTreeElement.setInspected(true); - - var parent = axNode.parentNode(); - if (parent) { - var ancestorChain = []; - var ancestor = parent; - while (ancestor) { - ancestorChain.unshift(ancestor); - ancestor = ancestor.parentNode(); - } - for (var ancestorNode of ancestorChain) { - var ancestorTreeElement = new Accessibility.AXNodeTreeElement(ancestorNode, this); - previousTreeElement.appendChild(ancestorTreeElement); - previousTreeElement.expand(); - previousTreeElement = ancestorTreeElement; - } - } - - previousTreeElement.appendChild(inspectedNodeTreeElement); - previousTreeElement.expand(); - - inspectedNodeTreeElement.selectable = true; - inspectedNodeTreeElement.setInspected(true); - inspectedNodeTreeElement.select(!this._selectedByUser /* omitFocus */, false); - inspectedNodeTreeElement.expand(); - this._preselectedTreeElement = inspectedNodeTreeElement; - - this.clearSelectedByUser(); - } - - /** - * @param {!Event} event - */ - _onKeyDown(event) { - if (!this._preselectedTreeElement) - return; - if (!event.path.some(element => element === this._preselectedTreeElement.listItemElement)) - return; - if (event.shiftKey || event.metaKey || event.ctrlKey) - return; - - var handled = false; - if (event.key === 'ArrowUp' && !event.altKey) - handled = this._preselectPrevious(); - else if (event.key === 'ArrowDown' && !event.altKey) - handled = this._preselectNext(); - else if (event.key === 'ArrowLeft') - handled = this._preselectedTreeElement.collapseOrAscend(event.altKey); - else if (event.key === 'ArrowRight') - handled = this._preselectedTreeElement.descendOrExpand(event.altKey); - else if (isEnterKey(event)) - handled = this._preselectedTreeElement.onenter(); - - if (handled) - event.consume(true); - } - - /** - * @return {boolean} - */ - _preselectPrevious() { - var previousElement = this._preselectedTreeElement.traversePreviousTreeElement(true); - if (!previousElement) - return false; - - previousElement.reveal(); - previousElement.setPreselected(true); - previousElement.focus(); - return true; - } - - /** - * @return {boolean} - */ - _preselectNext() { - var nextElement = this._preselectedTreeElement.traverseNextTreeElement(true); - if (!nextElement) - return false; - - nextElement.reveal(); - nextElement.setPreselected(true); - nextElement.focus(); - return true; - } - - /** - * @param {!Accessibility.AXNodeTreeElement} treeElement - */ - _setPreselectedTreeElement(treeElement) { - if (treeElement === this._preselectedTreeElement) - return; - if (this._preselectedTreeElement) - this._preselectedTreeElement.setPreselected(false); - this._preselectedTreeElement = treeElement; - } - - /** - * @param {!Event} event - */ - _onMouseLeave(event) { - this.setHoveredElement(null); - } - - /** - * @param {?Accessibility.AXNodeTreeElement} treeElement - */ - setHoveredElement(treeElement) { - if (treeElement === this._hoveredElement) - return; - if (this._hoveredElement) - this._hoveredElement.setHovered(false); - this._hoveredElement = treeElement; - if (!this._hoveredElement) { - if (!this.node()) - return; - // Highlight and scroll into view the currently inspected node. - this.node().domModel().overlayModel().nodeHighlightRequested(this.node().id); - } - } - - /** - * @param {!Accessibility.AccessibilityNode} axNode - */ - setInspectedNode(axNode) { - var axSidebarView = this._axSidebarView; - if (axNode.parentNode()) { - var inspectedDOMNode = UI.context.flavor(SDK.DOMNode); - axNode.deferredDOMNode().resolve(domNode => { - if (domNode !== inspectedDOMNode) - Common.Revealer.reveal(axNode.deferredDOMNode(), true /* omitFocus */); - else - axSidebarView.setNode(domNode); - }); - } else { - // Only set the node for the accessibility panel, not the Elements tree. - axNode.deferredDOMNode().resolve(domNode => { - axSidebarView.setNode(domNode); - }); - } - } - - /** - * @param {boolean} selectedByUser - */ - setSelectedByUser(selectedByUser) { - this._selectedByUser = true; - } - - clearSelectedByUser() { - delete this._selectedByUser; - } - - /** - * @return {!SDK.Target} - */ - target() { - return this.node().domModel().target(); - } -}; - -/** - * @unrestricted - */ -Accessibility.AXNodeTreeElement = class extends UI.TreeElement { - /** - * @param {!Accessibility.AccessibilityNode} axNode - * @param {!Accessibility.AXTreePane} treePane - */ - constructor(axNode, treePane) { - // Pass an empty title, the title gets made later in onattach. - super('', false); - - /** @type {!Accessibility.AccessibilityNode} */ - this._axNode = axNode; - - /** @type {!Accessibility.AXTreePane} */ - this._treePane = treePane; - - this.selectable = false; - this.paddingSize = 12; - this._preselected = false; - this._hovered = false; - - this.listItemElement.addEventListener('mousemove', this._onmousemove.bind(this), false); - this.listItemElement.addEventListener('mouseleave', this._onmouseleave.bind(this), false); - this.listItemElement.addEventListener('click', this._onClick.bind(this), false); - } - - /** - * @param {boolean} x - */ - setPreselected(x) { - if (this._preselected === x) - return; - this._preselected = x; - this.listItemElement.classList.toggle('hovered', x || this._hovered); - this.setFocusable(x); - if (this._preselected) { - this._treePane._setPreselectedTreeElement(this); - this.listItemElement.classList.toggle('hovered', true); - this._axNode.highlightDOMNode(); - } - } - - /** - * @param {boolean} x - */ - setHovered(x) { - if (this._hovered === x) - return; - this._hovered = x; - this.listItemElement.classList.toggle('hovered', x || this._preselected); - if (this._hovered) { - this._treePane.setHoveredElement(this); - this.listItemElement.classList.toggle('hovered', true); - this._axNode.highlightDOMNode(); - } - } - - focus() { - this.listItemElement.focus(); - } - - /** - * @param {boolean} focusable - */ - setFocusable(focusable) { - if (focusable) - this.listItemElement.setAttribute('tabIndex', 0); - else - this.listItemElement.removeAttribute('tabIndex'); - } - - /** - * @param {!Event} event - * @return {boolean} - * @override - */ - isEventWithinDisclosureTriangle(event) { - // Accessibility tree doesn't have a "disclosure triangle" per se. - return false; - } - - _onmousemove(event) { - if (this._preselected || this._inspected || !this._axNode.isDOMNode()) - return; - this.setHovered(true); - } - - _onmouseleave(event) { - if (this._inspected) - return; - this.setHovered(false); - } - - /** - * @return {!Accessibility.AccessibilityNode} - */ - axNode() { - return this._axNode; - } - - /** - * @param {boolean} inspected - */ - setInspected(inspected) { - this._inspected = inspected; - } - - /** - * @override - * @return {boolean} - */ - onenter() { - this.inspectDOMNode(); - return true; - } - - /** - * @override - * @param {!Event} event - * @return {boolean} - */ - ondblclick(event) { - if (!this.axNode().isDOMNode()) - return false; - this.inspectDOMNode(); - return true; - } - - /** - * @param {!Event} event - */ - _onClick(event) { - if (!this.axNode().isDOMNode() || this._inspected) - return; - this.inspectDOMNode(); - } - - - /** - * @override - */ - onpopulate() { - for (var child of this._axNode.children()) { - var childTreeElement = new Accessibility.AXNodeTreeElement(child, this._treePane); - this.appendChild(childTreeElement); - if (childTreeElement.isExpandable() && !child.hasOnlyUnloadedChildren()) - childTreeElement.expand(); - } - } - - inspectDOMNode() { - this._treePane.setSelectedByUser(true); - this._treePane.setInspectedNode(this._axNode); - } - - /** - * @override - */ - onattach() { - this._update(); - } - - _update() { - this.titleElement().removeChildren(); - - if (this._axNode.ignored()) { - this._appendIgnoredNodeElement(); - } else { - this._appendRoleElement(this._axNode.role()); - if (this._axNode.name() && this._axNode.name().value) { - this.titleElement().createChild('span', 'separator').textContent = '\u00A0'; - this._appendNameElement(/** @type {string} */ (this._axNode.name().value)); - } - } - - if (this._axNode.hasOnlyUnloadedChildren()) { - this.listItemElement.classList.add('children-unloaded'); - this.setExpandable(true); - } else { - this.setExpandable(!!this._axNode.numChildren()); - } - - if (!this._axNode.isDOMNode()) - this.listItemElement.classList.add('no-dom-node'); - } - - /** - * @override - */ - expand() { - if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) - return; - super.expand(); - } - - /** - * @override - */ - collapse() { - if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) - return; - - super.collapse(); - } - - /** - * @param {boolean} altKey - * @return {boolean} - * @override - */ - collapseOrAscend(altKey) { - if (this.expanded) { - if (altKey) - this.collapseRecursively(); - else - this.collapse(); - return true; - } - - if (!this.parent || this.parent.root) - return false; - - var nextElement = this.parent; - if (nextElement) { - nextElement.reveal(); - nextElement.setPreselected(true); - nextElement.focus(); - return true; - } - - return false; - } - - /** - * @param {boolean} altKey - * @return {boolean} - * @override - */ - descendOrExpand(altKey) { - if (!this.isExpandable()) - return false; - - if (!this.expanded) { - if (altKey) - this.expandRecursively(); - else - this.expand(); - return true; - } - - var nextElement = this.firstChild(); - if (nextElement) { - nextElement.reveal(); - nextElement.setPreselected(true); - nextElement.focus(); - return true; - } - - return false; - } - - /** - * @param {string} name - */ - _appendNameElement(name) { - var nameElement = createElement('span'); - nameElement.textContent = '"' + name + '"'; - nameElement.classList.add('ax-readable-string'); - this.titleElement().appendChild(nameElement); - } - - /** - * @param {?Protocol.Accessibility.AXValue} role - */ - _appendRoleElement(role) { - if (!role) - return; - - var roleElement = createElementWithClass('span', 'monospace'); - roleElement.classList.add(Accessibility.AXNodeTreeElement.RoleStyles[role.type]); - roleElement.setTextContentTruncatedIfNeeded(role.value || ''); - - this.titleElement().appendChild(roleElement); - } - - _appendIgnoredNodeElement() { - var ignoredNodeElement = createElementWithClass('span', 'monospace'); - ignoredNodeElement.textContent = Common.UIString('Ignored'); - ignoredNodeElement.classList.add('ax-tree-ignored-node'); - this.titleElement().appendChild(ignoredNodeElement); - } - - /** - * @param {boolean=} omitFocus - * @param {boolean=} selectedByUser - * @return {boolean} - * @override - */ - select(omitFocus, selectedByUser) { - this._treePane.setSelectedByUser(!!selectedByUser); - - return super.select(omitFocus, selectedByUser); - } -}; - -/** @type {!Object<string, string>} */ -Accessibility.AXNodeTreeElement.RoleStyles = { - internalRole: 'ax-internal-role', - role: 'ax-role', -};
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js index 41c8a98..6d691b0a 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityNodeView.js
@@ -8,6 +8,8 @@ constructor() { super(Common.UIString('Computed Properties')); + this.contentElement.classList.add('ax-subpane'); + this._noNodeInfo = this.createInfo(Common.UIString('No accessibility node')); this._ignoredInfo = this.createInfo(Common.UIString('Accessibility node not exposed'), 'ax-ignored-info hidden');
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js index a837dd9..b3c30ae 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilitySidebarView.js
@@ -10,8 +10,8 @@ this._node = null; this._axNode = null; this._sidebarPaneStack = UI.viewManager.createStackLocation(); - this._treeSubPane = new Accessibility.AXTreePane(this); - this._sidebarPaneStack.showView(this._treeSubPane); + this._breadcrumbsSubPane = new Accessibility.AXBreadcrumbsPane(this); + this._sidebarPaneStack.showView(this._breadcrumbsSubPane); this._ariaSubPane = new Accessibility.ARIAAttributesPane(); this._sidebarPaneStack.showView(this._ariaSubPane); this._axNodeSubPane = new Accessibility.AXNodeSubPane(); @@ -29,6 +29,13 @@ } /** + * @return {?Accessibility.AccessibilityNode} + */ + axNode() { + return this._axNode; + } + + /** * @param {?SDK.DOMNode} node */ setNode(node) { @@ -52,8 +59,8 @@ if (this._axNodeSubPane) this._axNodeSubPane.setAXNode(axNode); - if (this._treeSubPane) - this._treeSubPane.setAXNode(axNode); + if (this._breadcrumbsSubPane) + this._breadcrumbsSubPane.setAXNode(axNode); } /** @@ -63,7 +70,6 @@ */ doUpdate() { var node = this.node(); - this._treeSubPane.setNode(node); this._axNodeSubPane.setNode(node); this._ariaSubPane.setNode(node); if (!node) @@ -81,8 +87,10 @@ wasShown() { super.wasShown(); - this._treeSubPane.setNode(this.node()); + this._breadcrumbsSubPane.setNode(this.node()); + this._breadcrumbsSubPane.setAXNode(this.axNode()); this._axNodeSubPane.setNode(this.node()); + this._axNodeSubPane.setAXNode(this.axNode()); this._ariaSubPane.setNode(this.node()); SDK.targetManager.addModelListener(SDK.DOMModel, SDK.DOMModel.Events.AttrModified, this._onAttrChange, this);
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css index 53131c3..3e24358 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/accessibilityNode.css
@@ -8,6 +8,10 @@ background-color: rgba(0, 0, 0, 0.03); } +.widget.ax-subpane { + overflow-x: hidden; +} + .ax-computed-text { background-image: url(Images/speech.png); background-repeat: no-repeat; @@ -45,10 +49,6 @@ font-style: italic; } -span.ax-role { - font-weight: bold; -} - span.ax-internal-role { font-style: italic; } @@ -61,9 +61,13 @@ flex: none; } -.ax-tree-ignored-node { - font-style: italic; - opacity: 0.7; +.invalid { + text-decoration: line-through; +} + +.tree-outline label[is=dt-icon-label] { + position: relative; + left: -11px; } .tree-outline li { @@ -80,34 +84,67 @@ left: -2px; } -.tree-outline.ax-tree li::before { +.ax-breadcrumbs-ignored-node { + font-style: italic; + opacity: 0.7; +} + +.ax-breadcrumbs { + padding-top: 1px; + margin: 0; + position: relative; +} + +.ax-breadcrumbs .ax-node { + white-space: nowrap; + position: relative; + min-height: 16px; + align-items: baseline; + padding-left: 4px; + padding-right: 4px; + overflow-x: hidden; +} + +.ax-breadcrumbs .ax-node::before { -webkit-mask-image: url(Images/chevrons.png); + -webkit-mask-position: 0 0; -webkit-mask-size: 30px 10px; -webkit-mask-repeat: no-repeat; + background-color: rgb(48, 57, 66); + content: " "; + color: transparent; + text-shadow: none; + margin-right: -2px; + height: 12px; + width: 14px; + position: absolute; } -.tree-outline.ax-tree li.parent::before { +@media (-webkit-min-device-pixel-ratio: 1.1) { + .ax-breadcrumbs .ax-node::before { + -webkit-mask-image: url(Images/chevrons_2x.png); + } +} /* media */ + +.ax-breadcrumbs .ax-node:not(.parent):not(.children-unloaded)::before { + background-color: transparent; +} + +.ax-breadcrumbs .ax-node.parent::before { -webkit-mask-position: -20px 1px; } -.tree-outline.ax-tree li.children-unloaded::before { + +.ax-breadcrumbs .ax-node.children-unloaded::before { -webkit-mask-position: 0px 1px; + width: 13px; } -.tree-outline.ax-tree li.no-dom-node { +.ax-breadcrumbs .ax-node.no-dom-node { opacity: 0.5; } -.tree-outline.ax-tree li.children-unloaded::before { - opacity: 0.2; -} - -.invalid { - text-decoration: line-through; -} - -.tree-outline label[is=dt-icon-label] { - position: relative; - left: -11px; +.ax-breadcrumbs .ax-node.children-unloaded::before { + opacity: 0.4; } span.ax-value-undefined { @@ -147,14 +184,62 @@ display: none; } -.tree-outline li.preselected:not(.selected) .selection ( +.ax-breadcrumbs .ax-node { + text-overflow: ellipsis; + white-space: nowrap; + position: relative; + align-items: center; + min-height: 16px; + margin-top: 1px; + padding-top: 1px; +} + +.ax-breadcrumbs .ax-node.preselected:not(.inspected) .selection, +.ax-breadcrumbs .ax-node.hovered:not(.inspected) .selection { display: block; - left: 3px; - right: 3px; + left: 2px; + right: 2px; background-color: rgba(56, 121, 217, 0.1); border-radius: 5px; } -.tree-outline li.inspected .selection { +.ax-breadcrumbs .ax-node.preselected:not(.inspected):focus .selection { + border: 1px solid rgba(56, 121, 217, 0.4); +} + +.ax-breadcrumbs .ax-node .selection { + display: none; + z-index: -1; +} + +.ax-breadcrumbs .ax-node.inspected .selection { + display: block; + background-color: #ddd; +} + +.ax-breadcrumbs .ax-node.inspected:focus .selection { background-color: rgb(56, 121, 217); } + +.ax-breadcrumbs .ax-node.parent.inspected:focus::before { + background-color: white; +} + +.ax-breadcrumbs .ax-node.inspected:focus { + color: white; +} + +.ax-breadcrumbs .ax-node.inspected:focus * { + color: inherit; +} + +.ax-breadcrumbs .ax-node span { + flex-shrink: 0; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ax-breadcrumbs .ax-node .wrapper { + padding-left: 12px; + overflow-x: hidden; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/module.json b/third_party/WebKit/Source/devtools/front_end/accessibility/module.json index 06fe6f9..8107bb8 100644 --- a/third_party/WebKit/Source/devtools/front_end/accessibility/module.json +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/module.json
@@ -20,7 +20,7 @@ "ARIAAttributesView.js", "ARIAMetadata.js", "ARIAConfig.js", - "AXTreePane.js" + "AXBreadcrumbsPane.js" ], "skip_compilation": [ "ARIAConfig.js"
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js index 06d08c8..e1d5db3 100644 --- a/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js +++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/TimelineOverviewPane.js
@@ -159,6 +159,7 @@ this._overviewCalculator.setDisplayWidth(this._overviewGrid.clientWidth()); for (var i = 0; i < this._overviewControls.length; ++i) this._overviewControls[i].update(); + this._overviewGrid.updateDividers(this._overviewCalculator); this._updateMarkers(); this._updateWindow(); } @@ -191,7 +192,6 @@ this._overviewCalculator.reset(); this._overviewGrid.reset(); this._overviewGrid.setResizeEnabled(false); - this._overviewGrid.updateDividers(this._overviewCalculator); this._cursorEnabled = false; this._hideCursor(); this._markers = new Map();
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp index 4dd1f3e506..1b6d9af 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -912,8 +912,14 @@ // Passes by not crashing later during teardown } -TEST_F(CanvasRenderingContext2DTest, - DISABLED_GetImageDataDisablesAcceleration) { +#if defined(MEMORY_SANITIZER) +#define MAYBE_GetImageDataDisablesAcceleration \ + DISABLED_GetImageDataDisablesAcceleration +#else +#define MAYBE_GetImageDataDisablesAcceleration GetImageDataDisablesAcceleration +#endif + +TEST_F(CanvasRenderingContext2DTest, MAYBE_GetImageDataDisablesAcceleration) { bool saved_fixed_rendering_mode = RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled(); RuntimeEnabledFeatures::SetCanvas2dFixedRenderingModeEnabled(false);
diff --git a/third_party/WebKit/Source/modules/navigatorcontentutils/testing/NavigatorContentUtilsClientMock.h b/third_party/WebKit/Source/modules/navigatorcontentutils/testing/NavigatorContentUtilsClientMock.h index b5bc4aa..6f9cf40 100644 --- a/third_party/WebKit/Source/modules/navigatorcontentutils/testing/NavigatorContentUtilsClientMock.h +++ b/third_party/WebKit/Source/modules/navigatorcontentutils/testing/NavigatorContentUtilsClientMock.h
@@ -33,6 +33,8 @@ virtual void UnregisterProtocolHandler(const String& scheme, const KURL&); private: + // TODO(sashab): Make NavigatorContentUtilsClientMock non-virtual and test it + // using a WebFrameClient mock. NavigatorContentUtilsClientMock() : NavigatorContentUtilsClient(nullptr) {} typedef struct {
diff --git a/third_party/WebKit/Source/modules/vr/DEPS b/third_party/WebKit/Source/modules/vr/DEPS index fd6692e..3ea118a 100644 --- a/third_party/WebKit/Source/modules/vr/DEPS +++ b/third_party/WebKit/Source/modules/vr/DEPS
@@ -3,4 +3,5 @@ "+device/vr/vr_service.mojom-blink.h", "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/common/mailbox_holder.h", + "+ui/gfx/geometry", ]
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp index 0bc75ca1..c6bbbc0 100644 --- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -50,6 +50,24 @@ return kVREyeNone; } +class VRDisplayFrameRequestCallback : public FrameRequestCallback { + public: + explicit VRDisplayFrameRequestCallback(VRDisplay* vr_display) + : vr_display_(vr_display) {} + ~VRDisplayFrameRequestCallback() override {} + void handleEvent(double high_res_time_ms) override { + vr_display_->OnMagicWindowVSync(high_res_time_ms / 1000.0); + } + + DEFINE_INLINE_VIRTUAL_TRACE() { + visitor->Trace(vr_display_); + + FrameRequestCallback::Trace(visitor); + } + + Member<VRDisplay> vr_display_; +}; + } // namespace VRDisplay::VRDisplay(NavigatorVR* navigator_vr, @@ -142,6 +160,29 @@ << " start: pending_vrdisplay_raf_=" << pending_vrdisplay_raf_ << " in_animation_frame_=" << in_animation_frame_ << " did_submit_this_frame_=" << did_submit_this_frame_; + if (!pending_vrdisplay_raf_) + return; + Document* doc = navigator_vr_->GetDocument(); + if (!doc || !display_) + return; + // If we've switched from magic window to presenting, cancel the Document rAF + // and start the VrPresentationProvider VSync. + if (is_presenting_ && pending_vsync_id_ != -1) { + doc->CancelAnimationFrame(pending_vsync_id_); + pending_vsync_ = false; + pending_vsync_id_ = -1; + } + if (display_blurred_ || pending_vsync_) + return; + + if (!is_presenting_) { + display_->GetNextMagicWindowPose(ConvertToBaseCallback( + WTF::Bind(&VRDisplay::OnMagicWindowPose, WrapWeakPersistent(this)))); + pending_vsync_ = true; + pending_vsync_id_ = + doc->RequestAnimationFrame(new VRDisplayFrameRequestCallback(this)); + return; + } if (!pending_vrdisplay_raf_) return; @@ -167,18 +208,11 @@ // before rAF (b), after rAF (c), or not at all (d). If rAF isn't called at // all, there won't be future frames. - if (!vr_v_sync_provider_.is_bound()) { - ConnectVSyncProvider(); - } else if (!display_blurred_ && !pending_vsync_) { - pending_vsync_ = true; - vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( - WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); - } + pending_vsync_ = true; + vr_presentation_provider_->GetVSync(ConvertToBaseCallback( + WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this)))); - DVLOG(2) << __FUNCTION__ << " done:" - << " vr_v_sync_provider_.is_bound()=" - << vr_v_sync_provider_.is_bound() - << " pending_vsync_=" << pending_vsync_; + DVLOG(2) << __FUNCTION__ << " done: pending_vsync_=" << pending_vsync_; } int VRDisplay::requestAnimationFrame(FrameRequestCallback* callback) { @@ -209,7 +243,6 @@ void VRDisplay::OnBlur() { DVLOG(1) << __FUNCTION__; display_blurred_ = true; - vr_v_sync_provider_.reset(); navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( EventTypeNames::vrdisplayblur, true, false, this, "")); } @@ -217,7 +250,8 @@ void VRDisplay::OnFocus() { DVLOG(1) << __FUNCTION__; display_blurred_ = false; - ConnectVSyncProvider(); + RequestVSync(); + navigator_vr_->EnqueueVREvent(VRDisplayEvent::Create( EventTypeNames::vrdisplayfocus, true, false, this, "")); } @@ -360,8 +394,13 @@ submit_frame_client_binding_.Bind(mojo::MakeRequest(&submit_frame_client)); display_->RequestPresent( secure_context, std::move(submit_frame_client), + mojo::MakeRequest(&vr_presentation_provider_), ConvertToBaseCallback( WTF::Bind(&VRDisplay::OnPresentComplete, WrapPersistent(this)))); + vr_presentation_provider_.set_connection_error_handler( + ConvertToBaseCallback( + WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError, + WrapWeakPersistent(this)))); pending_present_request_ = true; } else { UpdateLayerBounds(); @@ -458,6 +497,9 @@ } is_presenting_ = true; + // Call RequestVSync to switch from the (internal) document rAF to the + // VrPresentationProvider VSync. + RequestVSync(); ReportPresentationResult(PresentationResult::kSuccess); UpdateLayerBounds(); @@ -491,43 +533,20 @@ if (!display_) return; - // Set up the texture bounds for the provided layer - device::mojom::blink::VRLayerBoundsPtr left_bounds = - device::mojom::blink::VRLayerBounds::New(); - device::mojom::blink::VRLayerBoundsPtr right_bounds = - device::mojom::blink::VRLayerBounds::New(); - - if (layer_.leftBounds().size() == 4) { - left_bounds->left = layer_.leftBounds()[0]; - left_bounds->top = layer_.leftBounds()[1]; - left_bounds->width = layer_.leftBounds()[2]; - left_bounds->height = layer_.leftBounds()[3]; - } else { - // Left eye defaults - left_bounds->left = 0.0f; - left_bounds->top = 0.0f; - left_bounds->width = 0.5f; - left_bounds->height = 1.0f; + // Left eye defaults + if (layer_.leftBounds().size() != 4) layer_.setLeftBounds({0.0f, 0.0f, 0.5f, 1.0f}); - } - - if (layer_.rightBounds().size() == 4) { - right_bounds->left = layer_.rightBounds()[0]; - right_bounds->top = layer_.rightBounds()[1]; - right_bounds->width = layer_.rightBounds()[2]; - right_bounds->height = layer_.rightBounds()[3]; - } else { - // Right eye defaults - right_bounds->left = 0.5f; - right_bounds->top = 0.0f; - right_bounds->width = 0.5f; - right_bounds->height = 1.0f; + // Right eye defaults + if (layer_.rightBounds().size() != 4) layer_.setRightBounds({0.5f, 0.0f, 0.5f, 1.0f}); - } - display_->UpdateLayerBounds(vr_frame_id_, std::move(left_bounds), - std::move(right_bounds), source_width_, - source_height_); + const Vector<float>& left = layer_.leftBounds(); + const Vector<float>& right = layer_.rightBounds(); + + vr_presentation_provider_->UpdateLayerBounds( + vr_frame_id_, WebFloatRect(left[0], left[1], left[2], left[3]), + WebFloatRect(right[0], right[1], right[2], right[3]), + WebSize(source_width_, source_height_)); } HeapVector<VRLayer> VRDisplay::getLayers() { @@ -673,14 +692,13 @@ pending_submit_frame_ = true; TRACE_EVENT_BEGIN0("gpu", "VRDisplay::SubmitFrame"); - display_->SubmitFrame(vr_frame_id_, - gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D)); + vr_presentation_provider_->SubmitFrame( + vr_frame_id_, gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D)); TRACE_EVENT_END0("gpu", "VRDisplay::SubmitFrame"); did_submit_this_frame_ = true; // If we were deferring a rAF-triggered vsync request, do this now. - if (pending_vrdisplay_raf_) - RequestVSync(); + RequestVSync(); // If preserveDrawingBuffer is false, must clear now. Normally this // happens as part of compositing, but that's not active while @@ -834,11 +852,12 @@ RequestVSync(); } } + if (pending_pose_) + frame_pose_ = std::move(pending_pose_); // Sanity check: If pending_vrdisplay_raf_ is true and the vsync provider // is connected, we must now have a pending vsync. - DCHECK(!pending_vrdisplay_raf_ || !vr_v_sync_provider_.is_bound() || - pending_vsync_); + DCHECK(!pending_vrdisplay_raf_ || pending_vsync_); // For GVR, we shut down normal vsync processing during VR presentation. // Trigger any callbacks on window.rAF manually so that they run after @@ -850,16 +869,16 @@ } } -void VRDisplay::OnVSync(device::mojom::blink::VRPosePtr pose, - WTF::TimeDelta time_delta, - int16_t frame_id, - device::mojom::blink::VRVSyncProvider::Status error) { +void VRDisplay::OnPresentingVSync( + device::mojom::blink::VRPosePtr pose, + WTF::TimeDelta time_delta, + int16_t frame_id, + device::mojom::blink::VRPresentationProvider::VSyncStatus status) { DVLOG(2) << __FUNCTION__; - v_sync_connection_failed_ = false; - switch (error) { - case device::mojom::blink::VRVSyncProvider::Status::SUCCESS: + switch (status) { + case device::mojom::blink::VRPresentationProvider::VSyncStatus::SUCCESS: break; - case device::mojom::blink::VRVSyncProvider::Status::CLOSING: + case device::mojom::blink::VRPresentationProvider::VSyncStatus::CLOSING: return; } pending_vsync_ = false; @@ -886,25 +905,29 @@ WrapWeakPersistent(this), timebase_ + time_delta.InSecondsF())); } -void VRDisplay::ConnectVSyncProvider() { - if (!FocusedOrPresenting() || vr_v_sync_provider_.is_bound()) - return; - display_->GetVRVSyncProvider(mojo::MakeRequest(&vr_v_sync_provider_)); - vr_v_sync_provider_.set_connection_error_handler(ConvertToBaseCallback( - WTF::Bind(&VRDisplay::OnVSyncConnectionError, WrapWeakPersistent(this)))); - if (pending_vrdisplay_raf_ && !display_blurred_) { - pending_vsync_ = true; - vr_v_sync_provider_->GetVSync(ConvertToBaseCallback( - WTF::Bind(&VRDisplay::OnVSync, WrapWeakPersistent(this)))); +void VRDisplay::OnMagicWindowVSync(double timestamp) { + DVLOG(2) << __FUNCTION__; + pending_vsync_ = false; + pending_vsync_id_ = -1; + vr_frame_id_ = -1; + Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask( + BLINK_FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledAnimations, + WrapWeakPersistent(this), timestamp)); +} + +void VRDisplay::OnMagicWindowPose(device::mojom::blink::VRPosePtr pose) { + if (!in_animation_frame_) { + frame_pose_ = std::move(pose); + } else { + pending_pose_ = std::move(pose); } } -void VRDisplay::OnVSyncConnectionError() { - vr_v_sync_provider_.reset(); - if (v_sync_connection_failed_) - return; - ConnectVSyncProvider(); - v_sync_connection_failed_ = true; +void VRDisplay::OnPresentationProviderConnectionError() { + vr_presentation_provider_.reset(); + ForceExitPresent(); + pending_vsync_ = false; + RequestVSync(); } ScriptedAnimationController& VRDisplay::EnsureScriptedAnimationController( @@ -917,7 +940,7 @@ void VRDisplay::Dispose() { display_client_binding_.Close(); - vr_v_sync_provider_.reset(); + vr_presentation_provider_.reset(); } ExecutionContext* VRDisplay::GetExecutionContext() const { @@ -941,10 +964,14 @@ } void VRDisplay::FocusChanged() { - // TODO(mthiesse): Blur/focus the display. DVLOG(1) << __FUNCTION__; - vr_v_sync_provider_.reset(); - ConnectVSyncProvider(); + if (is_presenting_) + return; + if (navigator_vr_->IsFocused()) { + OnFocus(); + } else { + OnBlur(); + } } bool VRDisplay::FocusedOrPresenting() {
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.h b/third_party/WebKit/Source/modules/vr/VRDisplay.h index 87ceae0..9e2f9540 100644 --- a/third_party/WebKit/Source/modules/vr/VRDisplay.h +++ b/third_party/WebKit/Source/modules/vr/VRDisplay.h
@@ -96,6 +96,8 @@ void FocusChanged(); + void OnMagicWindowVSync(double timestamp); + DECLARE_VIRTUAL_TRACE(); protected: @@ -139,12 +141,14 @@ OnActivateCallback on_handled) override; void OnDeactivate(device::mojom::blink::VRDisplayEventReason) override; - void OnVSync(device::mojom::blink::VRPosePtr, - WTF::TimeDelta, - int16_t frame_id, - device::mojom::blink::VRVSyncProvider::Status); - void ConnectVSyncProvider(); - void OnVSyncConnectionError(); + void OnPresentingVSync( + device::mojom::blink::VRPosePtr, + WTF::TimeDelta, + int16_t frame_id, + device::mojom::blink::VRPresentationProvider::VSyncStatus); + void OnPresentationProviderConnectionError(); + + void OnMagicWindowPose(device::mojom::blink::VRPosePtr); bool FocusedOrPresenting(); @@ -170,6 +174,7 @@ Member<VREyeParameters> eye_parameters_left_; Member<VREyeParameters> eye_parameters_right_; device::mojom::blink::VRPosePtr frame_pose_; + device::mojom::blink::VRPosePtr pending_pose_; // This frame ID is vr-specific and is used to track when frames arrive at the // VR compositor so that it knows which poses to use, when to apply bounds @@ -196,6 +201,7 @@ Member<ScriptedAnimationController> scripted_animation_controller_; bool pending_vrdisplay_raf_ = false; bool pending_vsync_ = false; + int pending_vsync_id_ = -1; bool in_animation_frame_ = false; bool did_submit_this_frame_ = false; bool in_display_activate_ = false; @@ -203,7 +209,6 @@ double timebase_ = -1; bool pending_previous_frame_render_ = false; bool pending_submit_frame_ = false; - bool v_sync_connection_failed_ = false; bool pending_present_request_ = false; device::mojom::blink::VRDisplayPtr display_; @@ -211,7 +216,7 @@ mojo::Binding<device::mojom::blink::VRSubmitFrameClient> submit_frame_client_binding_; mojo::Binding<device::mojom::blink::VRDisplayClient> display_client_binding_; - device::mojom::blink::VRVSyncProviderPtr vr_v_sync_provider_; + device::mojom::blink::VRPresentationProviderPtr vr_presentation_provider_; HeapDeque<Member<ScriptPromiseResolver>> pending_present_resolvers_; };
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 19139f9..aac5578 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -965,6 +965,8 @@ "graphics/UnacceleratedStaticBitmapImage.cpp", "graphics/UnacceleratedStaticBitmapImage.h", "graphics/WebGraphicsContext3DProviderWrapper.h", + "graphics/compositing/ContentLayerClientImpl.cpp", + "graphics/compositing/ContentLayerClientImpl.h", "graphics/compositing/PaintArtifactCompositor.cpp", "graphics/compositing/PaintArtifactCompositor.h", "graphics/compositing/PaintChunksToCcLayer.cpp",
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index 71f1f22..1f79ddf 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -243,7 +243,6 @@ }, { name: "CSSGridLayout", - settable_from_internals: true, status: "stable", }, {
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp new file mode 100644 index 0000000..c1e9cfb --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.cpp
@@ -0,0 +1,84 @@ +// 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. + +#include "platform/graphics/compositing/ContentLayerClientImpl.h" + +namespace blink { + +template class RasterInvalidationTrackingMap<const cc::Layer>; +static RasterInvalidationTrackingMap<const cc::Layer>& +CcLayersRasterInvalidationTrackingMap() { + DEFINE_STATIC_LOCAL(RasterInvalidationTrackingMap<const cc::Layer>, map, ()); + return map; +} + +ContentLayerClientImpl::~ContentLayerClientImpl() { + CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); +} + +template <typename T> +static std::unique_ptr<JSONArray> PointAsJSONArray(const T& point) { + std::unique_ptr<JSONArray> array = JSONArray::Create(); + array->PushDouble(point.X()); + array->PushDouble(point.Y()); + return array; +} + +template <typename T> +static std::unique_ptr<JSONArray> SizeAsJSONArray(const T& size) { + std::unique_ptr<JSONArray> array = JSONArray::Create(); + array->PushDouble(size.Width()); + array->PushDouble(size.Height()); + return array; +} + +void ContentLayerClientImpl::ResetTrackedRasterInvalidations() { + RasterInvalidationTracking* tracking = + CcLayersRasterInvalidationTrackingMap().Find(cc_picture_layer_.get()); + if (!tracking) + return; + + if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) + tracking->invalidations.clear(); + else + CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); +} + +RasterInvalidationTracking& +ContentLayerClientImpl::EnsureRasterInvalidationTracking() { + return CcLayersRasterInvalidationTrackingMap().Add(cc_picture_layer_.get()); +} + +std::unique_ptr<JSONObject> ContentLayerClientImpl::LayerAsJSON( + LayerTreeFlags flags) { + std::unique_ptr<JSONObject> json = JSONObject::Create(); + json->SetString("name", debug_name_); + + FloatPoint position(cc_picture_layer_->offset_to_transform_parent().x(), + cc_picture_layer_->offset_to_transform_parent().y()); + if (position != FloatPoint()) + json->SetArray("position", PointAsJSONArray(position)); + + IntSize bounds(cc_picture_layer_->bounds().width(), + cc_picture_layer_->bounds().height()); + if (!bounds.IsEmpty()) + json->SetArray("bounds", SizeAsJSONArray(bounds)); + + json->SetBoolean("contentsOpaque", cc_picture_layer_->contents_opaque()); + json->SetBoolean("drawsContent", cc_picture_layer_->DrawsContent()); + + if (flags & kLayerTreeIncludesDebugInfo) { + std::unique_ptr<JSONArray> paint_chunk_contents_array = JSONArray::Create(); + for (const auto& debug_data : paint_chunk_debug_data_) { + paint_chunk_contents_array->PushValue(debug_data->Clone()); + } + json->SetArray("paintChunkContents", std::move(paint_chunk_contents_array)); + } + + CcLayersRasterInvalidationTrackingMap().AsJSON(cc_picture_layer_.get(), + json.get()); + return json; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h new file mode 100644 index 0000000..87c93c9 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/compositing/ContentLayerClientImpl.h
@@ -0,0 +1,86 @@ +// 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. + +#ifndef ContentLayerClientImpl_h +#define ContentLayerClientImpl_h + +#include "cc/layers/content_layer_client.h" +#include "cc/layers/picture_layer.h" +#include "platform/PlatformExport.h" +#include "platform/graphics/GraphicsLayerClient.h" +#include "platform/graphics/paint/PaintChunk.h" +#include "platform/wtf/Noncopyable.h" +#include "platform/wtf/Vector.h" + +namespace blink { + +class JSONArray; +class JSONObject; +struct RasterInvalidationTracking; + +class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { + WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); + USING_FAST_MALLOC(ContentLayerClientImpl); + + public: + ContentLayerClientImpl(PaintChunk::Id paint_chunk_id) + : id_(paint_chunk_id), + debug_name_(paint_chunk_id.client.DebugName()), + cc_picture_layer_(cc::PictureLayer::Create(this)) {} + + ~ContentLayerClientImpl(); + + void SetDisplayList(scoped_refptr<cc::DisplayItemList> cc_display_item_list) { + cc_display_item_list_ = std::move(cc_display_item_list); + } + void SetPaintableRegion(const gfx::Rect& region) { + paintable_region_ = region; + } + + void AddPaintChunkDebugData(std::unique_ptr<JSONArray> json) { + paint_chunk_debug_data_.push_back(std::move(json)); + } + void ClearPaintChunkDebugData() { paint_chunk_debug_data_.clear(); } + + // cc::ContentLayerClient + gfx::Rect PaintableRegion() override { return paintable_region_; } + scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( + PaintingControlSetting) override { + return cc_display_item_list_; + } + bool FillsBoundsCompletely() const override { return false; } + size_t GetApproximateUnsharedMemoryUsage() const override { + // TODO(jbroman): Actually calculate memory usage. + return 0; + } + + void ResetTrackedRasterInvalidations(); + RasterInvalidationTracking& EnsureRasterInvalidationTracking(); + + void SetNeedsDisplayRect(const gfx::Rect& rect) { + cc_picture_layer_->SetNeedsDisplayRect(rect); + } + + std::unique_ptr<JSONObject> LayerAsJSON(LayerTreeFlags); + + scoped_refptr<cc::PictureLayer> CcPictureLayer() { return cc_picture_layer_; } + + bool Matches(const PaintChunk& paint_chunk) { + return paint_chunk.Matches(&id_); + } + + const String& DebugName() const { return debug_name_; } + + private: + PaintChunk::Id id_; + String debug_name_; + scoped_refptr<cc::PictureLayer> cc_picture_layer_; + scoped_refptr<cc::DisplayItemList> cc_display_item_list_; + gfx::Rect paintable_region_; + Vector<std::unique_ptr<JSONArray>> paint_chunk_debug_data_; +}; + +} // namespace blink + +#endif // ContentLayerClientImpl_h
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index ca04066..8dddedc 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -4,13 +4,13 @@ #include "platform/graphics/compositing/PaintArtifactCompositor.h" -#include "cc/layers/content_layer_client.h" #include "cc/layers/layer.h" #include "cc/layers/picture_layer.h" #include "cc/paint/display_item_list.h" #include "cc/trees/layer_tree_host.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/graphics/GraphicsContext.h" +#include "platform/graphics/compositing/ContentLayerClientImpl.h" #include "platform/graphics/compositing/PaintChunksToCcLayer.h" #include "platform/graphics/compositing/PropertyTreeManager.h" #include "platform/graphics/paint/ClipPaintPropertyNode.h" @@ -29,13 +29,6 @@ namespace blink { -template class RasterInvalidationTrackingMap<const cc::Layer>; -static RasterInvalidationTrackingMap<const cc::Layer>& -CcLayersRasterInvalidationTrackingMap() { - DEFINE_STATIC_LOCAL(RasterInvalidationTrackingMap<const cc::Layer>, map, ()); - return map; -} - template <typename T> static std::unique_ptr<JSONArray> PointAsJSONArray(const T& point) { std::unique_ptr<JSONArray> array = JSONArray::Create(); @@ -59,112 +52,6 @@ // http://crbug.com/692842#c4. static int g_s_property_tree_sequence_number = 1; -class PaintArtifactCompositor::ContentLayerClientImpl - : public cc::ContentLayerClient { - WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); - USING_FAST_MALLOC(ContentLayerClientImpl); - - public: - ContentLayerClientImpl(PaintChunk::Id paint_chunk_id) - : id_(paint_chunk_id), - debug_name_(paint_chunk_id.client.DebugName()), - cc_picture_layer_(cc::PictureLayer::Create(this)) {} - - ~ContentLayerClientImpl() { - CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); - } - - void SetDisplayList(scoped_refptr<cc::DisplayItemList> cc_display_item_list) { - cc_display_item_list_ = std::move(cc_display_item_list); - } - void SetPaintableRegion(gfx::Rect region) { paintable_region_ = region; } - - void AddPaintChunkDebugData(std::unique_ptr<JSONArray> json) { - paint_chunk_debug_data_.push_back(std::move(json)); - } - void ClearPaintChunkDebugData() { paint_chunk_debug_data_.clear(); } - - // cc::ContentLayerClient - gfx::Rect PaintableRegion() override { return paintable_region_; } - scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( - PaintingControlSetting) override { - return cc_display_item_list_; - } - bool FillsBoundsCompletely() const override { return false; } - size_t GetApproximateUnsharedMemoryUsage() const override { - // TODO(jbroman): Actually calculate memory usage. - return 0; - } - - void ResetTrackedRasterInvalidations() { - RasterInvalidationTracking* tracking = - CcLayersRasterInvalidationTrackingMap().Find(cc_picture_layer_.get()); - if (!tracking) - return; - - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) - tracking->invalidations.clear(); - else - CcLayersRasterInvalidationTrackingMap().Remove(cc_picture_layer_.get()); - } - - RasterInvalidationTracking& EnsureRasterInvalidationTracking() { - return CcLayersRasterInvalidationTrackingMap().Add(cc_picture_layer_.get()); - } - - void SetNeedsDisplayRect(const gfx::Rect& rect) { - cc_picture_layer_->SetNeedsDisplayRect(rect); - } - - std::unique_ptr<JSONObject> LayerAsJSON(LayerTreeFlags flags) { - std::unique_ptr<JSONObject> json = JSONObject::Create(); - json->SetString("name", debug_name_); - - FloatPoint position(cc_picture_layer_->offset_to_transform_parent().x(), - cc_picture_layer_->offset_to_transform_parent().y()); - if (position != FloatPoint()) - json->SetArray("position", PointAsJSONArray(position)); - - IntSize bounds(cc_picture_layer_->bounds().width(), - cc_picture_layer_->bounds().height()); - if (!bounds.IsEmpty()) - json->SetArray("bounds", SizeAsJSONArray(bounds)); - - json->SetBoolean("contentsOpaque", cc_picture_layer_->contents_opaque()); - json->SetBoolean("drawsContent", cc_picture_layer_->DrawsContent()); - - if (flags & kLayerTreeIncludesDebugInfo) { - std::unique_ptr<JSONArray> paint_chunk_contents_array = - JSONArray::Create(); - for (const auto& debug_data : paint_chunk_debug_data_) { - paint_chunk_contents_array->PushValue(debug_data->Clone()); - } - json->SetArray("paintChunkContents", - std::move(paint_chunk_contents_array)); - } - - CcLayersRasterInvalidationTrackingMap().AsJSON(cc_picture_layer_.get(), - json.get()); - return json; - } - - scoped_refptr<cc::PictureLayer> CcPictureLayer() { return cc_picture_layer_; } - - bool Matches(const PaintChunk& paint_chunk) { - return paint_chunk.Matches(&id_); - } - - const String& DebugName() const { return debug_name_; } - - private: - PaintChunk::Id id_; - String debug_name_; - scoped_refptr<cc::PictureLayer> cc_picture_layer_; - scoped_refptr<cc::DisplayItemList> cc_display_item_list_; - gfx::Rect paintable_region_; - Vector<std::unique_ptr<JSONArray>> paint_chunk_debug_data_; -}; - PaintArtifactCompositor::PaintArtifactCompositor() { if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; @@ -213,7 +100,7 @@ return layer; } -std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> +std::unique_ptr<ContentLayerClientImpl> PaintArtifactCompositor::ClientForPaintChunk( const PaintChunk& paint_chunk, const PaintArtifact& paint_artifact) {
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h index 812d82e..3f1bdd87 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -25,6 +25,7 @@ namespace blink { +class ContentLayerClientImpl; class JSONObject; class PaintArtifact; class WebLayer; @@ -115,8 +116,6 @@ PaintArtifactCompositor(); - class ContentLayerClientImpl; - // Collects the PaintChunks into groups which will end up in the same // cc layer. This is the entry point of the layerization algorithm. void CollectPendingLayers(const PaintArtifact&,
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp index d0e10b6..2f6d1541 100644 --- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp +++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -89,6 +89,12 @@ return FilePathToWebString(BlinkRootFilePath()); } +String ExecutableDir() { + base::FilePath path; + base::PathService::Get(base::DIR_EXE, &path); + return FilePathToWebString(base::MakeAbsoluteFilePath(path)); +} + String WebTestDataPath(const String& relative_path) { return FilePathToWebString( BlinkRootFilePath()
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.h b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.h index 3b94f961..6f18cad 100644 --- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.h +++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.h
@@ -52,6 +52,9 @@ // /src/third_party/WebKit. String BlinkRootDir(); +// Returns directory containing the current executable as absolute path. +String ExecutableDir(); + // Returns test data absolute path for webkit_unit_tests, i.e. // <blinkRootDir>/Source/web/tests/data/<relativePath>. // It returns the top web test directory if |relativePath| was not specified.
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp index 2edbacc..826b5b9c 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -648,6 +648,29 @@ cursor_overridden_ = overridden; } +void ChromeClientImpl::AutoscrollStart(WebFloatPoint viewport_point, + LocalFrame* local_frame) { + LocalFrame& local_root = local_frame->LocalFrameRoot(); + if (WebFrameWidgetBase* widget = + WebLocalFrameImpl::FromFrame(&local_root)->FrameWidget()) + widget->Client()->AutoscrollStart(viewport_point); +} + +void ChromeClientImpl::AutoscrollFling(WebFloatSize velocity, + LocalFrame* local_frame) { + LocalFrame& local_root = local_frame->LocalFrameRoot(); + if (WebFrameWidgetBase* widget = + WebLocalFrameImpl::FromFrame(&local_root)->FrameWidget()) + widget->Client()->AutoscrollFling(velocity); +} + +void ChromeClientImpl::AutoscrollEnd(LocalFrame* local_frame) { + LocalFrame& local_root = local_frame->LocalFrameRoot(); + if (WebFrameWidgetBase* widget = + WebLocalFrameImpl::FromFrame(&local_root)->FrameWidget()) + widget->Client()->AutoscrollEnd(); +} + String ChromeClientImpl::AcceptLanguages() { return web_view_->Client()->AcceptLanguages(); }
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h index 7d79131..4bbb67e 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.h +++ b/third_party/WebKit/Source/web/ChromeClientImpl.h
@@ -171,6 +171,10 @@ // ChromeClientImpl: void SetNewWindowNavigationPolicy(WebNavigationPolicy); + void AutoscrollStart(WebFloatPoint viewport_point, LocalFrame*) override; + void AutoscrollFling(WebFloatSize velocity, LocalFrame*) override; + void AutoscrollEnd(LocalFrame*) override; + bool HasOpenedPopup() const override; PopupMenu* OpenPopupMenu(LocalFrame&, HTMLSelectElement&) override; PagePopup* OpenPagePopup(PagePopupClient*) override;
diff --git a/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp b/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp index 21486f1..1bb5e60 100644 --- a/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp +++ b/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp
@@ -102,7 +102,7 @@ protected: void SetUp() override { - helper_.Initialize(false, &web_frame_client_, &web_view_client_); + helper_.Initialize(&web_frame_client_, &web_view_client_); WebView()->SetUseExternalPopupMenus(true); } void TearDown() override {
diff --git a/third_party/WebKit/Source/web/PageOverlayTest.cpp b/third_party/WebKit/Source/web/PageOverlayTest.cpp index 0f798fe..078be62 100644 --- a/third_party/WebKit/Source/web/PageOverlayTest.cpp +++ b/third_party/WebKit/Source/web/PageOverlayTest.cpp
@@ -70,12 +70,12 @@ enum CompositingMode { kAcceleratedCompositing, kUnacceleratedCompositing }; void Initialize(CompositingMode compositing_mode) { - helper_.Initialize( - false /* enableJavascript */, nullptr /* webFrameClient */, - nullptr /* webViewClient */, nullptr /* webWidgetClient */, - compositing_mode == kAcceleratedCompositing - ? EnableAcceleratedCompositing - : DisableAcceleratedCompositing); + helper_.Initialize(nullptr /* webFrameClient */, + nullptr /* webViewClient */, + nullptr /* webWidgetClient */, + compositing_mode == kAcceleratedCompositing + ? EnableAcceleratedCompositing + : DisableAcceleratedCompositing); GetWebView()->Resize(WebSize(kViewportWidth, kViewportHeight)); GetWebView()->UpdateAllLifecyclePhases(); ASSERT_EQ(compositing_mode == kAcceleratedCompositing,
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index db4a4fd..cfb0aa80c 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -614,16 +614,6 @@ return WebRect(); } -bool WebLocalFrameImpl::HasHorizontalScrollbar() const { - return GetFrame() && GetFrame()->View() && - GetFrame()->View()->HorizontalScrollbar(); -} - -bool WebLocalFrameImpl::HasVerticalScrollbar() const { - return GetFrame() && GetFrame()->View() && - GetFrame()->View()->VerticalScrollbar(); -} - WebView* WebLocalFrameImpl::View() const { return ViewImpl(); }
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.h b/third_party/WebKit/Source/web/WebLocalFrameImpl.h index eb11c27..cea685ea 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.h +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.h
@@ -100,8 +100,6 @@ WebSize ContentsSize() const override; bool HasVisibleContent() const override; WebRect VisibleContentRect() const override; - bool HasHorizontalScrollbar() const override; - bool HasVerticalScrollbar() const override; WebView* View() const override; WebDocument GetDocument() const override; WebPerformance Performance() const override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 6f75a156..bef0c5ea 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -677,7 +677,8 @@ ->GetEventHandler() .IsScrollbarHandlingGestures()) break; - EndActiveFlingAnimation(); + if (event.source_device != kWebGestureDeviceSyntheticAutoscroll) + EndActiveFlingAnimation(); position_on_fling_start_ = WebPoint(event.x, event.y); global_position_on_fling_start_ = WebPoint(event.global_x, event.global_y); @@ -1984,10 +1985,12 @@ WebGestureDevice last_fling_source_device = fling_source_device_; EndActiveFlingAnimation(); - WebGestureEvent end_scroll_event = CreateGestureScrollEventFromFling( - WebInputEvent::kGestureScrollEnd, last_fling_source_device); - MainFrameImpl()->GetFrame()->GetEventHandler().HandleGestureScrollEnd( - end_scroll_event); + if (last_fling_source_device != kWebGestureDeviceSyntheticAutoscroll) { + WebGestureEvent end_scroll_event = CreateGestureScrollEventFromFling( + WebInputEvent::kGestureScrollEnd, last_fling_source_device); + MainFrameImpl()->GetFrame()->GetEventHandler().HandleGestureScrollEnd( + end_scroll_event); + } } }
diff --git a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp index 01195df8..77d2535 100644 --- a/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp +++ b/third_party/WebKit/Source/web/tests/ActivityLoggerTest.cpp
@@ -75,7 +75,7 @@ activity_logger_ = new TestActivityLogger(); V8DOMActivityLogger::SetActivityLogger(kIsolatedWorldId, String(), WTF::WrapUnique(activity_logger_)); - web_view_helper_.Initialize(true); + web_view_helper_.Initialize(); script_controller_ = &web_view_helper_.WebView() ->MainFrameImpl() ->GetFrame()
diff --git a/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp b/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp index 8221e81..009e193 100644 --- a/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp +++ b/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp
@@ -73,8 +73,8 @@ WebViewBase* Initialize(const std::string& page_name = "large-div.html") { // Load a page with large body and set viewport size to 400x400 to ensure // main frame is scrollable. - helper_.InitializeAndLoad(base_url_ + page_name, true, nullptr, nullptr, - nullptr, &ConfigureSettings); + helper_.InitializeAndLoad(base_url_ + page_name, nullptr, nullptr, nullptr, + &ConfigureSettings); GetWebView()->Resize(IntSize(400, 400)); return GetWebView();
diff --git a/third_party/WebKit/Source/web/tests/ChromeClientImplTest.cpp b/third_party/WebKit/Source/web/tests/ChromeClientImplTest.cpp index a29276b8..29062ff3 100644 --- a/third_party/WebKit/Source/web/tests/ChromeClientImplTest.cpp +++ b/third_party/WebKit/Source/web/tests/ChromeClientImplTest.cpp
@@ -72,7 +72,7 @@ const WebString& name, WebNavigationPolicy, bool) override { - return web_view_helper_.InitializeWithOpener(opener, true); + return web_view_helper_.InitializeWithOpener(opener); } private: @@ -82,7 +82,7 @@ class CreateWindowTest : public testing::Test { protected: void SetUp() override { - web_view_ = helper_.Initialize(false, nullptr, &web_view_client_); + web_view_ = helper_.Initialize(nullptr, &web_view_client_); main_frame_ = helper_.LocalMainFrame(); chrome_client_impl_ = ToChromeClientImpl(&web_view_->GetPage()->GetChromeClient());
diff --git a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp index 3da497e..82c60df 100644 --- a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp +++ b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
@@ -42,7 +42,7 @@ base_url_("http://www.test.com/") {} void SetUp() override { - helper_.Initialize(true, nullptr, &mock_web_view_client_, nullptr, + helper_.Initialize(nullptr, &mock_web_view_client_, nullptr, &ConfigureSettings); GetWebView()->Resize(IntSize(320, 240)); } @@ -101,7 +101,6 @@ private: static void ConfigureSettings(WebSettings* settings) { - settings->SetJavaScriptEnabled(true); settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); }
diff --git a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp index 633a29bf..93420f8 100644 --- a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp +++ b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
@@ -167,7 +167,7 @@ ChildDelegate child_delegate; MainFrameClient main_frame_client(child_delegate); - web_view_helper_.Initialize(false, &main_frame_client); + web_view_helper_.Initialize(&main_frame_client); // This doesn't go through the mocked URL load path: it's just intended to // setup a situation where didReceiveData() can be invoked reentrantly. @@ -188,7 +188,7 @@ TEST_F(DocumentLoaderTest, isCommittedButEmpty) { WebViewBase* web_view_impl = - web_view_helper_.InitializeAndLoad("about:blank", true); + web_view_helper_.InitializeAndLoad("about:blank"); EXPECT_TRUE(ToLocalFrame(web_view_impl->GetPage()->MainFrame()) ->Loader() .GetDocumentLoader()
diff --git a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp index c86b921..e8bf322 100644 --- a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp +++ b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
@@ -65,8 +65,8 @@ protected: void SetUp() override { - // We want the images to load and JavaScript to be on. - helper_.Initialize(true, nullptr, nullptr, nullptr, &ConfigureSettings); + // We want the images to load. + helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings); } void TearDown() override {
diff --git a/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp b/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp index 0f8a7cd..d360af9a 100644 --- a/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp +++ b/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp
@@ -98,7 +98,7 @@ testing::WebTestDataPath(), WebString::FromUTF8(file_name)); WebViewBase* web_view = - web_view_helper_.Initialize(true, 0, nullptr, &client); + web_view_helper_.Initialize(nullptr, nullptr, &client); web_view->Resize(WebSize(800, 1200)); LoadFrame(web_view->MainFrame(), base_url_ + file_name); document_ = web_view_helper_.WebView()
diff --git a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp index f16cbd9..b71b715fb 100644 --- a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp +++ b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp
@@ -177,8 +177,8 @@ TEST_P(LayoutGeometryMapTest, SimpleGeometryMapTest) { RegisterMockedHttpURLLoad("rgm_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_test.html", true, 0, 0); + WebView* web_view = + web_view_helper.InitializeAndLoad(base_url_ + "rgm_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -222,7 +222,7 @@ RegisterMockedHttpURLLoad("rgm_transformed_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_transformed_test.html", true, 0, 0); + base_url_ + "rgm_transformed_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -281,7 +281,7 @@ RegisterMockedHttpURLLoad("rgm_fixed_position_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_fixed_position_test.html", true, 0, 0); + base_url_ + "rgm_fixed_position_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -319,7 +319,7 @@ RegisterMockedHttpURLLoad("rgm_contains_fixed_position_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_contains_fixed_position_test.html", true, 0, 0); + base_url_ + "rgm_contains_fixed_position_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -365,8 +365,8 @@ RegisterMockedHttpURLLoad("rgm_iframe_test.html"); RegisterMockedHttpURLLoad("rgm_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_iframe_test.html", true, 0, 0); + WebView* web_view = + web_view_helper.InitializeAndLoad(base_url_ + "rgm_iframe_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -461,8 +461,8 @@ TEST_P(LayoutGeometryMapTest, ColumnTest) { RegisterMockedHttpURLLoad("rgm_column_test.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_column_test.html", true, 0, 0); + WebView* web_view = + web_view_helper.InitializeAndLoad(base_url_ + "rgm_column_test.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -511,7 +511,7 @@ RegisterMockedHttpURLLoad("rgm_float_under_inline.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "rgm_float_under_inline.html", true, 0, 0); + base_url_ + "rgm_float_under_inline.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp b/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp index 2946a2e..8f409e7 100644 --- a/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp +++ b/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp
@@ -128,8 +128,7 @@ "foobar</a>" "<div id='page_text'>Lorem ipsum dolor sit amet</div>"; - web_view_ = helper_.Initialize(false, &test_frame_client_, nullptr, nullptr, - [](WebSettings* settings) {}); + web_view_ = helper_.Initialize(&test_frame_client_); main_frame_ = web_view_->MainFrameImpl(); FrameTestHelpers::LoadHTMLString( main_frame_, kHTMLString, URLTestHelpers::ToKURL("http://foobar.com")); @@ -267,7 +266,7 @@ "<div id='empty_div' style='width: 100px; height: 100px;'></div>" "<span id='text_div'>Sometexttoshow</span>"; - web_view_ = helper_.Initialize(false); + web_view_ = helper_.Initialize(); main_frame_ = web_view_->MainFrameImpl(); FrameTestHelpers::LoadHTMLString( main_frame_, kHTMLString, URLTestHelpers::ToKURL("http://foobar.com"));
diff --git a/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp b/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp index 69b3c9a..345719b 100644 --- a/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp +++ b/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp
@@ -87,11 +87,10 @@ void RunTest(const std::string& filename) { std::string base_url("http://www.example.com/"); std::string file_name(filename); - bool execute_script = true; URLTestHelpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(base_url), blink::testing::WebTestDataPath(), WebString::FromUTF8(file_name)); - web_view_helper.InitializeAndLoad(base_url + file_name, execute_script); + web_view_helper.InitializeAndLoad(base_url + file_name); } void TearDown() override {
diff --git a/third_party/WebKit/Source/web/tests/LocalFrameClientImplTest.cpp b/third_party/WebKit/Source/web/tests/LocalFrameClientImplTest.cpp index cf032b8f..2a458b02 100644 --- a/third_party/WebKit/Source/web/tests/LocalFrameClientImplTest.cpp +++ b/third_party/WebKit/Source/web/tests/LocalFrameClientImplTest.cpp
@@ -62,7 +62,7 @@ ON_CALL(web_frame_client_, UserAgentOverride()) .WillByDefault(Return(WebString())); - helper_.Initialize(true, &web_frame_client_); + helper_.Initialize(&web_frame_client_); // FIXME: http://crbug.com/363843. This needs to find a better way to // not create graphics layers. helper_.WebView()->GetSettings()->SetAcceleratedCompositingEnabled(false);
diff --git a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp index e39af10..cb75b42d 100644 --- a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp +++ b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
@@ -168,8 +168,7 @@ URLTestHelpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(base_url), blink::testing::WebTestDataPath(), WebString::FromUTF8(file_name)); - const bool kRunJavascript = true; - web_view_helper_.Initialize(kRunJavascript); + web_view_helper_.Initialize(); web_view_helper_.WebView()->SetPrerendererClient(&prerenderer_client_); FrameTestHelpers::LoadFrame(web_view_helper_.WebView()->MainFrame(),
diff --git a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp index bef142c..26cdc98 100644 --- a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp +++ b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
@@ -44,8 +44,8 @@ RegisterMockedHttpURLLoad("long_scroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "long_scroll.html", true, 0, 0); + WebViewBase* web_view = + web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases(); @@ -76,8 +76,8 @@ RegisterMockedHttpURLLoad("long_scroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "long_scroll.html", true, 0, 0); + WebViewBase* web_view = + web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html"); web_view->Resize(WebSize(1000, 1000)); web_view->UpdateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp index 2ef18d8..0640019 100644 --- a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp +++ b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
@@ -159,7 +159,7 @@ FrameTestHelpers::TestWebViewClient* client) { RuntimeEnabledFeatures::SetSetRootScrollerEnabled(true); - helper_.InitializeAndLoad(url, true, nullptr, client, nullptr, + helper_.InitializeAndLoad(url, nullptr, client, nullptr, &ConfigureSettings); // Initialize browser controls to be shown.
diff --git a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp index a9050d6..9e97553 100644 --- a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp +++ b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
@@ -82,7 +82,7 @@ class ScreenWakeLockTest : public ::testing::Test { protected: void SetUp() override { - web_view_helper_.Initialize(true, &test_web_frame_client_); + web_view_helper_.Initialize(&test_web_frame_client_); URLTestHelpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8("http://example.com/"), testing::WebTestDataPath(), WebString::FromUTF8("foo.html"));
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp index 36d1b80a..a476fa3 100644 --- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp +++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -62,7 +62,7 @@ ScrollingCoordinatorTest() : ScopedRootLayerScrollingForTest(GetParam()), base_url_("http://www.test.com/") { - helper_.Initialize(true, nullptr, &mock_web_view_client_, nullptr, + helper_.Initialize(nullptr, &mock_web_view_client_, nullptr, &ConfigureSettings); GetWebView()->Resize(IntSize(320, 240)); @@ -126,7 +126,6 @@ private: static void ConfigureSettings(WebSettings* settings) { - settings->SetJavaScriptEnabled(true); settings->SetAcceleratedCompositingEnabled(true); settings->SetPreferCompositingToLCDTextEnabled(true); }
diff --git a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp index 5dc170e..e8dce12 100644 --- a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp +++ b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
@@ -202,8 +202,8 @@ testing::WebTestDataPath(), WebString::FromUTF8(file)); // Note that JavaScript must be enabled for shadow DOM tests. - WebView* web_view = - web_view_helper_.InitializeAndLoad(base_url_ + file, true, 0, 0, &client); + WebView* web_view = web_view_helper_.InitializeAndLoad( + base_url_ + file, nullptr, nullptr, &client); // Set size to enable hit testing, and avoid line wrapping for consistency // with browser.
diff --git a/third_party/WebKit/Source/web/tests/ViewportTest.cpp b/third_party/WebKit/Source/web/tests/ViewportTest.cpp index eab67c4..7f9d74e 100644 --- a/third_party/WebKit/Source/web/tests/ViewportTest.cpp +++ b/third_party/WebKit/Source/web/tests/ViewportTest.cpp
@@ -116,7 +116,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-1.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -135,7 +135,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-2.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -154,7 +154,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-3.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -173,7 +173,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-4.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -192,7 +192,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-5.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -211,7 +211,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-6.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -230,7 +230,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-7.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -249,7 +249,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-8.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -268,7 +268,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-9.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -287,7 +287,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-10.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -306,7 +306,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-11.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -325,7 +325,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-12.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -344,7 +344,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-13.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -363,7 +363,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-14.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -382,7 +382,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-15.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -401,7 +401,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-16.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -420,7 +420,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-17.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -439,7 +439,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-18.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -458,7 +458,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-19.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -477,7 +477,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-20.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -496,7 +496,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-21.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -515,7 +515,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-22.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -534,7 +534,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-23.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -553,7 +553,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-24.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -572,7 +572,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-25.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -591,7 +591,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-26.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -610,7 +610,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-27.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -629,7 +629,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-28.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -648,7 +648,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-29.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -667,7 +667,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-30.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -686,7 +686,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-31.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -705,7 +705,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-32.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -724,7 +724,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-33.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -743,7 +743,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-34.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -762,7 +762,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-35.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -781,7 +781,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-36.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -800,7 +800,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-37.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -819,7 +819,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-38.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -838,7 +838,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-39.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -857,7 +857,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-40.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -876,7 +876,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-41.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -895,7 +895,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-42.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -914,7 +914,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-43.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -933,7 +933,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-44.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -952,7 +952,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-45.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -971,7 +971,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-46.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -990,7 +990,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-47.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1009,7 +1009,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-48.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1028,7 +1028,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-49.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1047,7 +1047,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-50.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1066,7 +1066,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-51.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1085,7 +1085,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-52.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1104,7 +1104,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-53.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1123,7 +1123,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-54.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1142,7 +1142,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-55.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1161,7 +1161,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-56.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1180,7 +1180,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-57.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1199,7 +1199,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-58.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1218,7 +1218,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-59.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1237,7 +1237,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-60.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1256,7 +1256,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-61.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1275,7 +1275,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-62.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1294,7 +1294,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-63.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1313,7 +1313,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-64.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1332,7 +1332,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-65.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1351,7 +1351,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-66.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1370,7 +1370,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-67.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1389,7 +1389,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-68.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1408,7 +1408,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-69.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1427,7 +1427,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-70.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1446,7 +1446,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-71.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1465,7 +1465,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-72.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1484,7 +1484,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-73.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1503,7 +1503,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-74.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1522,7 +1522,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-75.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1541,7 +1541,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-76.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1560,7 +1560,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-77.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1579,7 +1579,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-78.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1598,7 +1598,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-79.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1617,7 +1617,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-80.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1636,7 +1636,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-81.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1655,7 +1655,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-82.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1674,7 +1674,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-83.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1693,7 +1693,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-84.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1712,7 +1712,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-85.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1731,7 +1731,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-86.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1750,7 +1750,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-87.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1769,7 +1769,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-88.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1788,7 +1788,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-90.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1807,7 +1807,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-100.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1826,7 +1826,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-101.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1845,7 +1845,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-102.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1864,7 +1864,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-103.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1883,7 +1883,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-104.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1902,7 +1902,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-105.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1921,7 +1921,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-106.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1940,7 +1940,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-107.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1959,7 +1959,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-108.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1978,7 +1978,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-109.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -1997,7 +1997,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-110.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2016,7 +2016,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-111.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2035,7 +2035,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-112.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2054,7 +2054,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-113.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2073,7 +2073,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-114.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2092,7 +2092,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-115.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2111,7 +2111,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-116.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2130,7 +2130,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-117.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2149,7 +2149,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-118.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2168,7 +2168,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-119.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2187,7 +2187,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-120.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2206,7 +2206,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-121.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2225,7 +2225,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-122.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2244,7 +2244,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-123.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2263,7 +2263,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-124.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2282,7 +2282,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-125.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2301,7 +2301,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-126.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2320,7 +2320,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-127.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2339,7 +2339,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-129.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2358,7 +2358,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-130.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2377,7 +2377,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-131.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2396,7 +2396,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-132.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2415,7 +2415,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-133.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2434,7 +2434,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-134.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2453,7 +2453,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-135.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2472,7 +2472,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-136.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2491,7 +2491,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-137.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2510,7 +2510,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-138.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2529,8 +2529,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-handheldfriendly.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-handheldfriendly.html", nullptr, + nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 320, 352); @@ -2555,7 +2555,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-merge-quirk-1.html", true, nullptr, + base_url_ + "viewport/viewport-legacy-merge-quirk-1.html", nullptr, nullptr, nullptr, SetQuirkViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2574,7 +2574,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-merge-quirk-2.html", true, nullptr, + base_url_ + "viewport/viewport-legacy-merge-quirk-2.html", nullptr, nullptr, nullptr, SetQuirkViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2596,8 +2596,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-mobileoptimized.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-mobileoptimized.html", nullptr, + nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2616,8 +2616,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-mobileoptimized-2.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-mobileoptimized-2.html", nullptr, + nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2636,8 +2636,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-mobileoptimized-2.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-mobileoptimized-2.html", nullptr, + nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2656,8 +2656,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-2.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-2.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2676,8 +2676,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-3.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-3.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2696,8 +2696,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-4.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-4.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2716,8 +2716,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-5.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-5.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2736,8 +2736,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-6.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-6.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2756,8 +2756,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-7.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-7.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2776,8 +2776,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-8.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-8.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -2796,8 +2796,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-ordering-10.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-ordering-10.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 800, 600); @@ -2810,8 +2810,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-xhtmlmp.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-xhtmlmp.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 320, 352); @@ -2832,7 +2832,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( base_url_ + "viewport/viewport-legacy-xhtmlmp-misplaced-doctype.html", - true, nullptr, nullptr, nullptr, SetViewportSettings); + nullptr, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 320, 352); @@ -2850,8 +2850,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-xhtmlmp-ordering.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-xhtmlmp-ordering.html", nullptr, + nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 320, 352); @@ -2869,8 +2869,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-xhtmlmp.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-xhtmlmp.html", nullptr, nullptr, + nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 320, 352); @@ -2915,7 +2915,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( base_url_ + "viewport/viewport-limits-adjusted-for-no-user-scale.html", - true, nullptr, nullptr, nullptr, SetViewportSettings); + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->UpdateAllLifecyclePhases(); Page* page = web_view_helper.WebView()->GetPage(); @@ -2932,7 +2932,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-limits-adjusted-for-user-scale.html", true, + base_url_ + "viewport/viewport-limits-adjusted-for-user-scale.html", nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->UpdateAllLifecyclePhases(); @@ -2952,7 +2952,7 @@ web_view_helper.InitializeAndLoad( base_url_ + "viewport/viewport-gpu-rasterization-disabled-without-viewport.html", - true, nullptr, nullptr, nullptr, SetViewportSettings); + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_FALSE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); @@ -2960,16 +2960,15 @@ // supports GPU raster unconditionally. web_view_helper.InitializeAndLoad( base_url_ + - "viewport/viewport-gpu-rasterization-disabled-without-viewport.html", - true); + "viewport/viewport-gpu-rasterization-disabled-without-viewport.html"); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); RegisterMockedHttpURLLoad("viewport/viewport-gpu-rasterization.html"); web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-gpu-rasterization.html", true, nullptr, - nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-gpu-rasterization.html", nullptr, nullptr, + nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); @@ -2979,14 +2978,14 @@ web_view_helper.InitializeAndLoad( base_url_ + "viewport/viewport-gpu-rasterization-expanded-heuristics.html", - true, nullptr, nullptr, nullptr, SetViewportSettings); + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); RegisterMockedHttpURLLoad("viewport/viewport-1.html"); web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-1.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() @@ -2994,7 +2993,7 @@ RegisterMockedHttpURLLoad("viewport/viewport-15.html"); web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-15.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() @@ -3002,7 +3001,7 @@ RegisterMockedHttpURLLoad("viewport/viewport-130.html"); web_view_helper.InitializeAndLoad(base_url_ + "viewport/viewport-130.html", - true, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() @@ -3010,16 +3009,16 @@ RegisterMockedHttpURLLoad("viewport/viewport-legacy-handheldfriendly.html"); web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-handheldfriendly.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-handheldfriendly.html", nullptr, + nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); RegisterMockedHttpURLLoad("viewport/viewport-legacy-mobileoptimized.html"); web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-legacy-handheldfriendly.html", true, - nullptr, nullptr, nullptr, SetViewportSettings); + base_url_ + "viewport/viewport-legacy-handheldfriendly.html", nullptr, + nullptr, nullptr, SetViewportSettings); web_view_helper.WebView()->Resize(WebSize(640, 480)); EXPECT_TRUE(web_view_helper.WebView() ->MatchesHeuristicsForGpuRasterizationForTesting()); @@ -3045,7 +3044,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-1.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-1.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3068,7 +3067,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-2.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-2.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3095,7 +3094,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-3.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-3.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3124,7 +3123,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-4.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-4.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3153,7 +3152,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-5.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-5.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3183,7 +3182,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-6.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-6.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage(); @@ -3211,7 +3210,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport/viewport-warnings-7.html", true, &web_frame_client, + base_url_ + "viewport/viewport-warnings-7.html", &web_frame_client, nullptr, nullptr, SetViewportSettings); Page* page = web_view_helper.WebView()->GetPage();
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp index 324dba7..e4c82c7 100644 --- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp +++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -115,7 +115,7 @@ void (*override_settings_func)(WebSettings*) = 0) { if (!override_settings_func) override_settings_func = &ConfigureSettings; - helper_.Initialize(true, nullptr, &mock_web_view_client_, nullptr, + helper_.Initialize(nullptr, &mock_web_view_client_, nullptr, override_settings_func); WebViewImpl()->SetDefaultPageScaleLimits(1, 4); } @@ -124,7 +124,7 @@ void (*override_settings_func)(WebSettings*) = 0) { if (!override_settings_func) override_settings_func = &ConfigureAndroidSettings; - helper_.Initialize(true, nullptr, &mock_web_view_client_, nullptr, + helper_.Initialize(nullptr, &mock_web_view_client_, nullptr, override_settings_func); WebViewImpl()->SetDefaultPageScaleLimits(0.25f, 5); } @@ -2111,13 +2111,9 @@ // Make sure a composited background-attachment:fixed background gets resized // when using inert (non-layout affecting) browser controls. TEST_P(VisualViewportTest, ResizeCompositedAndFixedBackground) { - std::unique_ptr<FrameTestHelpers::TestWebViewClient> - fake_compositing_web_view_client = - WTF::MakeUnique<FrameTestHelpers::TestWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, fake_compositing_web_view_client.get(), nullptr, - &configureAndroidCompositing); + nullptr, nullptr, nullptr, &configureAndroidCompositing); int page_width = 640; int page_height = 480; @@ -2193,7 +2189,7 @@ TEST_P(VisualViewportTest, ResizeNonCompositedAndFixedBackground) { FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, nullptr, nullptr, &configureAndroidNonCompositing); + nullptr, nullptr, nullptr, &configureAndroidNonCompositing); int page_width = 640; int page_height = 480; @@ -2290,13 +2286,9 @@ // Make sure a browser control resize with background-attachment:not-fixed // background doesn't cause invalidation or layout. TEST_P(VisualViewportTest, ResizeNonFixedBackgroundNoLayoutOrInvalidation) { - std::unique_ptr<FrameTestHelpers::TestWebViewClient> - fake_compositing_web_view_client = - WTF::MakeUnique<FrameTestHelpers::TestWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, fake_compositing_web_view_client.get(), nullptr, - &configureAndroidCompositing); + nullptr, nullptr, nullptr, &configureAndroidCompositing); int page_width = 640; int page_height = 480; @@ -2369,13 +2361,9 @@ } TEST_P(VisualViewportTest, InvalidateLayoutViewWhenDocumentSmallerThanView) { - std::unique_ptr<FrameTestHelpers::TestWebViewClient> - fake_compositing_web_view_client = - WTF::MakeUnique<FrameTestHelpers::TestWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, fake_compositing_web_view_client.get(), nullptr, - &configureAndroidCompositing); + nullptr, nullptr, nullptr, &configureAndroidCompositing); int page_width = 320; int page_height = 590;
diff --git a/third_party/WebKit/Source/web/tests/WebDocumentSubresourceFilterTest.cpp b/third_party/WebKit/Source/web/tests/WebDocumentSubresourceFilterTest.cpp index 82b8b8df..efa0915 100644 --- a/third_party/WebKit/Source/web/tests/WebDocumentSubresourceFilterTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebDocumentSubresourceFilterTest.cpp
@@ -90,7 +90,7 @@ WebDocumentSubresourceFilterTest() : base_url_("http://internal.test/") { RegisterMockedHttpURLLoad("white-1x1.png"); RegisterMockedHttpURLLoad("foo_with_image.html"); - web_view_helper_.Initialize(false /* enableJavascript */, &client_); + web_view_helper_.Initialize(&client_); } void LoadDocument(bool allow_subresources) {
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp index 2d31f855..7107a03 100644 --- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -275,7 +275,7 @@ void InitializeTextSelectionWebView( const std::string& url, FrameTestHelpers::WebViewHelper* web_view_helper) { - web_view_helper->InitializeAndLoad(url, true); + web_view_helper->InitializeAndLoad(url); web_view_helper->WebView()->GetSettings()->SetDefaultFontSize(12); web_view_helper->Resize(WebSize(640, 480)); } @@ -395,7 +395,7 @@ RegisterMockedHttpURLLoad("zero_sized_iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "iframes_test.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "iframes_test.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); EXPECT_EQ(web_view_helper.WebView()->MainFrame(), @@ -443,7 +443,7 @@ RegisterMockedHttpURLLoad("foo.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( @@ -462,7 +462,7 @@ RegisterMockedHttpURLLoad("bar.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( @@ -493,7 +493,7 @@ RegisterMockedHttpURLLoad("foo.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); auto callback = [](const v8::FunctionCallbackInfo<v8::Value>& info) { info.GetReturnValue().Set(V8String(info.GetIsolate(), "hello")); @@ -520,7 +520,7 @@ RegisterMockedHttpURLLoad("foo.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); auto callback = [](const v8::FunctionCallbackInfo<v8::Value>& info) { info.GetReturnValue().Set(V8String(info.GetIsolate(), "hello")); @@ -554,7 +554,7 @@ RegisterMockedHttpURLLoad("foo.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); auto callback = [](const v8::FunctionCallbackInfo<v8::Value>& info) { info.GetReturnValue().Set(v8::Boolean::New( @@ -594,7 +594,7 @@ RegisterMockedHttpURLLoad("visible_iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "single_iframe.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "single_iframe.html"); v8::HandleScope scope(v8::Isolate::GetCurrent()); ScriptExecutionCallbackHelper callback_helper( @@ -633,9 +633,8 @@ TEST_P(ParameterizedWebFrameTest, ChromePageJavascript) { RegisterMockedChromeURLLoad("history.html"); - // Pass true to enable JavaScript. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(chrome_url_ + "history.html", true); + web_view_helper.InitializeAndLoad(chrome_url_ + "history.html"); // Try to run JS against the chrome-style URL. FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), @@ -653,9 +652,8 @@ TEST_P(ParameterizedWebFrameTest, ChromePageNoJavascript) { RegisterMockedChromeURLLoad("history.html"); - /// Pass true to enable JavaScript. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(chrome_url_ + "history.html", true); + web_view_helper.InitializeAndLoad(chrome_url_ + "history.html"); // Try to run JS against the chrome-style URL after prohibiting it. WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs("chrome"); @@ -677,9 +675,7 @@ RegisterMockedURLLoadFromBase("http://internal.test:0/", file_name); FrameTestHelpers::WebViewHelper web_view_helper; - - /// Pass true to enable JavaScript. - web_view_helper.InitializeAndLoad(base_url_ + file_name, true); + web_view_helper.InitializeAndLoad(base_url_ + file_name); // Setting host to "hostname:" should be treated as "hostname:0". FrameTestHelpers::LoadFrame( @@ -702,9 +698,7 @@ RegisterMockedURLLoadFromBase("http://internal.test:0/", file_name); FrameTestHelpers::WebViewHelper web_view_helper; - - /// Pass true to enable JavaScript. - web_view_helper.InitializeAndLoad(base_url_ + file_name, true); + web_view_helper.InitializeAndLoad(base_url_ + file_name); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), "javascript:location.port = ''; void 0;"); @@ -741,7 +735,7 @@ TEST_P(ParameterizedWebFrameTest, DidClearWindowObjectIsNotRecursive) { EvaluateOnLoadWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, &web_frame_client); + web_view_helper.InitializeAndLoad("about:blank", &web_frame_client); EXPECT_TRUE(web_frame_client.was_executed_); } @@ -776,7 +770,7 @@ class WebFrameCSSCallbackTest : public ::testing::Test { protected: WebFrameCSSCallbackTest() { - frame_ = helper_.InitializeAndLoad("about:blank", true, &client_) + frame_ = helper_.InitializeAndLoad("about:blank", &client_) ->MainFrame() ->ToWebLocalFrame(); } @@ -1009,9 +1003,8 @@ TEST_P(ParameterizedWebFrameTest, DispatchMessageEventWithOriginCheck) { RegisterMockedHttpURLLoad("postmessage_test.html"); - // Pass true to enable JavaScript. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "postmessage_test.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "postmessage_test.html"); // Send a message with the correct origin. WebSecurityOrigin correct_origin( @@ -1123,9 +1116,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); Document* document = ToLocalFrame(web_view_helper.WebView()->GetPage()->MainFrame()) @@ -1154,8 +1146,8 @@ FixedLayoutTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client, + nullptr, ConfigureAndroid); Document* document = ToLocalFrame(web_view_helper.WebView()->GetPage()->MainFrame()) @@ -1179,9 +1171,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "iframe_reload.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "iframe_reload.html", nullptr, + &client, nullptr, ConfigureAndroid); LocalFrame* main_frame = ToLocalFrame(web_view_helper.WebView()->GetPage()->MainFrame()); @@ -1226,7 +1217,7 @@ int viewport_height = 0; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); EXPECT_EQ(viewport_width, web_view_helper.WebView() @@ -1252,9 +1243,8 @@ client.screen_info_.device_scale_factor = 2; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1282,7 +1272,7 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "fixed_layout.html"); @@ -1324,7 +1314,7 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "wide_document.html"); @@ -1364,8 +1354,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-auto-initial-scale.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "viewport-auto-initial-scale.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); EXPECT_EQ(0.25f, web_view_helper.WebView()->PageScaleFactor()); @@ -1390,8 +1380,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-auto-initial-scale.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "viewport-auto-initial-scale.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1410,7 +1400,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", true, nullptr, + web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); @@ -1432,8 +1422,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-auto-initial-scale.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "viewport-auto-initial-scale.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1463,7 +1453,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, + base_url_ + "viewport-wide-2x-initial-scale.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); @@ -1493,9 +1483,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1521,7 +1510,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); FrameTestHelpers::LoadFrame( @@ -1551,7 +1540,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport-height-1000.html", - true, nullptr, &client, nullptr, + nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); @@ -1574,8 +1563,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-2x-initial-scale.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "viewport-2x-initial-scale.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1603,7 +1592,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, + base_url_ + "viewport-wide-2x-initial-scale.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1621,9 +1610,8 @@ float enforced_page_scale_factor = 2.0f; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.WebView()->SetInitialPageScaleOverride( @@ -1657,8 +1645,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-auto-initial-scale.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "viewport-auto-initial-scale.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.WebView()->SetInitialPageScaleOverride( enforced_page_scale_factor); @@ -1680,7 +1668,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, + base_url_ + "viewport-wide-2x-initial-scale.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetInitialPageScaleOverride( enforced_page_scale_factor); @@ -1713,8 +1701,8 @@ for (size_t i = 0; i < WTF_ARRAY_LENGTH(pages); ++i) { for (int quirk_enabled = 0; quirk_enabled <= 1; ++quirk_enabled) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + pages[i], true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + pages[i], nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView() ->GetSettings() ->SetClobberUserAgentInitialScaleQuirk(quirk_enabled); @@ -1741,8 +1729,8 @@ float enforced_page_scale_factor = 0.5; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, nullptr, &client, - nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad("about:blank", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); web_view_helper.WebView()->GetSettings()->SetLoadWithOverviewMode(false); @@ -1771,8 +1759,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "0-by-0.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "0-by-0.html", nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetForceZeroLayoutHeight(true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -1793,8 +1781,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "0-by-0.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "0-by-0.html", nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetForceZeroLayoutHeight(true); web_view_helper.WebView()->UpdateAllLifecyclePhases(); @@ -1870,9 +1858,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); EXPECT_LE(viewport_height, web_view_helper.WebView() @@ -1928,7 +1915,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport-device-width.html", - true, 0, &client); + nullptr, &client); WebSettings* settings = web_view_helper.WebView()->GetSettings(); settings->SetViewportMetaEnabled(false); settings->SetViewportEnabled(true); @@ -1965,8 +1952,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "button.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "button.html", nullptr, &client, + nullptr, ConfigureAndroid); // set view height to zero so that if the height of the view is not // successfully updated during later resizes touch events will fail // (as in not hit content included in the view) @@ -2081,9 +2068,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetForceZeroLayoutHeight(true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -2109,9 +2095,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "200-by-300.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.WebView()->GetSettings()->SetForceZeroLayoutHeight(true); @@ -2134,8 +2119,8 @@ int viewport_height = 800; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, nullptr, &client, - nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad("about:blank", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.WebView()->GetSettings()->SetViewportMetaLayoutSizeQuirk( @@ -2163,8 +2148,8 @@ int viewport_height = 800; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, nullptr, &client, - nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad("about:blank", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); web_view_helper.WebView()->GetSettings()->SetViewportMetaLayoutSizeQuirk( @@ -2192,8 +2177,8 @@ int viewport_height = 800; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, nullptr, &client, - nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad("about:blank", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.WebView()->GetSettings()->SetViewportMetaLayoutSizeQuirk( @@ -2271,7 +2256,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetViewportMetaZeroValuesQuirk( true); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); @@ -2307,7 +2292,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr); + web_view_helper.Initialize(nullptr, &client); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "body-overflow-hidden.html"); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -2328,7 +2313,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr); + web_view_helper.Initialize(nullptr, &client); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "body-overflow-hidden-short.html"); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -2352,7 +2337,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr); + web_view_helper.Initialize(nullptr, &client); web_view_helper.WebView() ->GetSettings() ->SetIgnoreMainFrameOverflowHiddenQuirk(true); @@ -2375,7 +2360,7 @@ float expected_page_scale_factor = 0.5f; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetViewportMetaZeroValuesQuirk( true); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); @@ -2414,9 +2399,8 @@ int viewport_height = 48; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); int prev_layout_count = @@ -2442,9 +2426,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); int prev_layout_count = @@ -2469,9 +2452,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetPageScaleFactor(3); @@ -2491,7 +2473,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "fixed_layout.html"); @@ -2518,7 +2500,7 @@ int viewport_height = 48; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", true, nullptr, + web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -2562,9 +2544,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetPageScaleFactor(2); @@ -2597,8 +2578,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-target-densitydpi-high.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-target-densitydpi-high.html", nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView() ->GetSettings() @@ -2642,8 +2623,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-target-densitydpi-device.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-target-densitydpi-device.html", nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView() ->GetSettings() @@ -2685,7 +2666,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( base_url_ + "viewport-target-densitydpi-device-and-fixed-width.html", - true, nullptr, &client, nullptr, ConfigureAndroid); + nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView() ->GetSettings() @@ -2721,8 +2702,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-initial-scale-less-than-1.html", true, nullptr, - &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-initial-scale-less-than-1.html", nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.WebView() ->GetSettings() ->SetSupportDeprecatedTargetDensityDPI(true); @@ -2760,7 +2741,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-initial-scale-less-than-1-device-width.html", true, + base_url_ + "viewport-initial-scale-less-than-1-device-width.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView() ->GetSettings() @@ -2800,7 +2781,7 @@ float enforced_page_scale_factor = 5.0f; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", true, nullptr, + web_view_helper.InitializeAndLoad(base_url_ + "large-div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); @@ -2836,8 +2817,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-initial-scale-and-user-scalable-no.html", true, - nullptr, &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-initial-scale-and-user-scalable-no.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetViewportMetaNonUserScalableQuirk( true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -2870,8 +2851,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-initial-scale-and-user-scalable-no.html", true, - nullptr, &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-initial-scale-and-user-scalable-no.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView() ->GetSettings() ->SetSupportDeprecatedTargetDensityDPI(true); @@ -2909,8 +2890,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "viewport-2x-initial-scale-non-user-scalable.html", true, - nullptr, &client, nullptr, ConfigureAndroid); + base_url_ + "viewport-2x-initial-scale-non-user-scalable.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->GetSettings()->SetViewportMetaNonUserScalableQuirk( true); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); @@ -2943,9 +2924,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "no_viewport_tag.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); web_view_helper.WebView()->GetSettings()->SetWideViewportQuirkEnabled(true); web_view_helper.WebView()->GetSettings()->SetUseWideViewport(false); @@ -2962,7 +2942,7 @@ FixedLayoutTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "viewport-inside-media.html", - true, nullptr, &client, nullptr, + nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(640, 480)); @@ -2986,7 +2966,7 @@ FixedLayoutTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(640, 480)); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "viewport-and-media.html"); @@ -3012,7 +2992,7 @@ FixedLayoutTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, &client, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(800, 600)); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), base_url_ + "viewport-lengths.html"); @@ -3050,7 +3030,7 @@ static_cast<float>(viewport_size.width) / viewport_size.height; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + url, true, nullptr, nullptr, + web_view_helper.InitializeAndLoad(base_url_ + url, nullptr, nullptr, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); @@ -3169,9 +3149,8 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "fixed_layout.html", nullptr, + &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); LocalFrameView* view = @@ -3200,7 +3179,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "no_scale_for_you.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "no_scale_for_you.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.25f, 5); @@ -3238,9 +3217,8 @@ fake_compositing_web_view_client = WTF::MakeUnique<FakeCompositingWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, - fake_compositing_web_view_client.get(), nullptr, - &ConfigureCompositingWebView); + web_view_helper.Initialize(nullptr, fake_compositing_web_view_client.get(), + nullptr, &ConfigureCompositingWebView); web_view_helper.Resize(WebSize(view_width, view_height)); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), @@ -3305,7 +3283,7 @@ float double_tap_zoom_already_legible_ratio = 1.2f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_scale_for_auto_zoom_into_div_test.html", false, nullptr, + base_url_ + "get_scale_for_auto_zoom_into_div_test.html", nullptr, nullptr, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.01f, 4); @@ -3372,8 +3350,8 @@ float double_tap_zoom_already_legible_ratio = 1.2f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_wide_div_for_auto_zoom_test.html", false, nullptr, - nullptr, nullptr, ConfigureAndroid); + base_url_ + "get_wide_div_for_auto_zoom_test.html", nullptr, nullptr, + nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.WebView()->SetPageScaleFactor(1.0f); @@ -3409,9 +3387,8 @@ int viewport_width = 640 / kDeviceScaleFactor; int viewport_height = 1280 / kDeviceScaleFactor; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "very_tall_div.html", true, - nullptr, nullptr, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "very_tall_div.html", nullptr, + nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.WebView()->SetPageScaleFactor(1.0f); @@ -3439,8 +3416,8 @@ float double_tap_zoom_already_legible_ratio = 1.2f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_multiple_divs_for_auto_zoom_test.html", false, nullptr, - nullptr, nullptr, ConfigureAndroid); + base_url_ + "get_multiple_divs_for_auto_zoom_test.html", nullptr, nullptr, + nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetDefaultPageScaleLimits(0.5f, 4); web_view_helper.WebView()->SetDeviceScaleFactor(kDeviceScaleFactor); @@ -3497,8 +3474,8 @@ float double_tap_zoom_already_legible_ratio = 1.2f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", false, - nullptr, nullptr, nullptr, ConfigureAndroid); + base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", nullptr, + nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetDeviceScaleFactor(1.5f); web_view_helper.WebView()->SetMaximumLegibleScale(1.f); @@ -3578,8 +3555,8 @@ float maximum_legible_scale_factor = 1.13f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", false, - nullptr, nullptr, nullptr, ConfigureAndroid); + base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", nullptr, + nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetMaximumLegibleScale( maximum_legible_scale_factor); @@ -3686,8 +3663,8 @@ float accessibility_font_scale_factor = 1.13f; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", false, - nullptr, nullptr, nullptr, ConfigureAndroid); + base_url_ + "get_scale_bounds_check_for_auto_zoom_test.html", nullptr, + nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.WebView()->SetMaximumLegibleScale(1.f); web_view_helper.WebView()->UpdateAllLifecyclePhases(); @@ -3792,9 +3769,8 @@ RegisterMockedHttpURLLoad("block_bound.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "block_bound.html", false, - nullptr, nullptr, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "block_bound.html", nullptr, + nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(300, 300)); IntRect rect_back = IntRect(0, 0, 200, 200); @@ -4191,7 +4167,7 @@ RegisterMockedHttpURLLoad("textbox.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "textbox.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "textbox.html"); web_view_helper.Resize(WebSize(640, 480)); WebLocalFrame* main_frame = web_view_helper.WebView()->MainFrameImpl(); @@ -4233,8 +4209,7 @@ TestReloadDoesntRedirectWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "form.html", false, - &web_frame_client); + web_view_helper.InitializeAndLoad(base_url_ + "form.html", &web_frame_client); web_view_helper.WebView()->MainFrame()->Reload( WebFrameLoadType::kReloadBypassingCache); @@ -4266,7 +4241,7 @@ ClearScrollStateOnCommitWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + first_url, true, &client); + web_view_helper.InitializeAndLoad(base_url_ + first_url, &client); web_view_helper.Resize(WebSize(kPageWidth, kPageHeight)); web_view_helper.WebView()->MainFrame()->SetScrollOffset( WebSize(kPageWidth / 4, kPageHeight / 4)); @@ -4328,7 +4303,7 @@ const std::string second_url = "http://internal.test"; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(first_url, true); + web_view_helper.InitializeAndLoad(first_url); WebDataSource* data_source = web_view_helper.WebView()->MainFrameImpl()->DataSource(); @@ -4347,7 +4322,7 @@ RegisterMockedHttpURLLoad("visible_iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "iframe_redirect.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "iframe_redirect.html"); // Pump pending requests one more time. The test page loads script that // navigates. FrameTestHelpers::PumpPendingRequestsForFrameToLoad( @@ -4372,8 +4347,8 @@ RegisterMockedHttpURLLoad("autofocus_input_field_iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad( - base_url_ + "iframe_clear_focused_node_test.html", true); + web_view_helper.InitializeAndLoad(base_url_ + + "iframe_clear_focused_node_test.html"); // Clear the focused node. web_view_helper.WebView()->ClearFocusedElement(); @@ -4398,7 +4373,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; RegisterMockedHttpURLLoad("editable_elements.html"); WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "editable_elements.html", true, &counter); + base_url_ + "editable_elements.html", &counter); WebKeyboardEvent tab_down(WebInputEvent::kKeyDown, WebInputEvent::kNoModifiers, @@ -4521,7 +4496,7 @@ release_notifications); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "context_notifications_test.html", true, &web_frame_client); + base_url_ + "context_notifications_test.html", &web_frame_client); WebLocalFrameBase* main_frame = web_view_helper.WebView()->MainFrameImpl(); WebFrame* child_frame = main_frame->FirstChild(); @@ -4570,7 +4545,7 @@ release_notifications); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "context_notifications_test.html", true, &web_frame_client); + base_url_ + "context_notifications_test.html", &web_frame_client); // Refresh, we should get two release notifications and two more create // notifications. @@ -4618,7 +4593,7 @@ release_notifications); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "context_notifications_test.html", true, &web_frame_client); + base_url_ + "context_notifications_test.html", &web_frame_client); // Add an isolated world. web_frame_client.Reset(); @@ -4726,7 +4701,7 @@ TEST_P(ParameterizedWebFrameTest, GetContentAsPlainText) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true); + web_view_helper.InitializeAndLoad("about:blank"); // We set the size because it impacts line wrapping, which changes the // resulting text value. web_view_helper.Resize(WebSize(640, 480)); @@ -4771,7 +4746,7 @@ TEST_P(ParameterizedWebFrameTest, GetFullHtmlOfPage) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true); + web_view_helper.InitializeAndLoad("about:blank"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); // Generate a simple test case. @@ -4818,7 +4793,7 @@ TestExecuteScriptDuringDidCreateScriptContext web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "hello_world.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "hello_world.html", &web_frame_client); FrameTestHelpers::ReloadFrame(web_view_helper.WebView()->MainFrame()); @@ -4856,7 +4831,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find_in_page_frame.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "find_in_page_frame.html", &client); web_view_helper.Resize(WebSize(640, 480)); web_view_helper.WebView()->SetMaximumLegibleScale(1.f); @@ -4927,7 +4902,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find_match_count.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "find_match_count.html", &client); web_view_helper.WebView()->Resize(WebSize(640, 480)); RunPendingTasks(); @@ -4986,8 +4961,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", true, - &client); + web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5028,8 +5002,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", true, - &client); + web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5068,8 +5041,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", true, - &client); + web_view_helper.InitializeAndLoad(base_url_ + "find_in_page.html", &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5109,7 +5081,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "find_in_generated_frame.html", - true, &client); + &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5138,7 +5110,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find.html", true, &client); + web_view_helper.InitializeAndLoad(base_url_ + "find.html", &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5192,7 +5164,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "find.html", true, &client); + web_view_helper.InitializeAndLoad(base_url_ + "find.html", &client); web_view_helper.Resize(WebSize(640, 480)); RunPendingTasks(); @@ -5267,7 +5239,7 @@ FindUpdateWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &client); + web_view_helper.Initialize(&client); WebLocalFrameBase* frame = web_view_helper.WebView()->MainFrameImpl(); FrameTestHelpers::LoadHTMLString(frame, html, @@ -5953,8 +5925,7 @@ RuntimeEnabledFeatures::SetCompositedSelectionUpdateEnabled(true); RegisterMockedHttpURLLoad("Ahem.ttf"); - web_view_helper_.Initialize(true, nullptr, &fake_selection_web_view_client_, - nullptr); + web_view_helper_.Initialize(nullptr, &fake_selection_web_view_client_); web_view_helper_.WebView()->GetSettings()->SetDefaultFontSize(12); web_view_helper_.WebView()->SetDefaultPageScaleLimits(1, 1); web_view_helper_.Resize(WebSize(640, 480)); @@ -6204,7 +6175,7 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, 0, &client); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client); web_view_helper.Resize(WebSize(1000, 1000)); client.ResetTriggered(); @@ -6259,7 +6230,7 @@ // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "disambiguation_popup_no_container.html", true, 0, &client); + base_url_ + "disambiguation_popup_no_container.html", nullptr, &client); web_view_helper.Resize(WebSize(1000, 1000)); client.ResetTriggered(); @@ -6276,8 +6247,8 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(1000, 1000)); client.ResetTriggered(); @@ -6310,8 +6281,8 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client, + nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(1000, 1000)); client.ResetTriggered(); @@ -6342,8 +6313,8 @@ DisambiguationPopupTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, nullptr, - &client, nullptr, ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client, + nullptr, ConfigureAndroid); WebViewBase* web_view_impl = web_view_helper.WebView(); ASSERT_TRUE(web_view_impl); @@ -6399,7 +6370,7 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + html_file, true, 0, &client); + web_view_helper.InitializeAndLoad(base_url_ + html_file, nullptr, &client); web_view_helper.Resize(WebSize(kViewportWidth, kViewportHeight)); // Click somewhere where the popup shouldn't appear. @@ -6431,7 +6402,7 @@ // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "disambiguation_popup_page_scale.html", true, 0, &client); + base_url_ + "disambiguation_popup_page_scale.html", nullptr, &client); web_view_helper.Resize(WebSize(1000, 1000)); client.ResetTriggered(); @@ -6483,7 +6454,7 @@ TestSubstituteDataWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, &web_frame_client); + web_view_helper.InitializeAndLoad("about:blank", &web_frame_client); WebFrame* frame = web_view_helper.WebView()->MainFrame(); // Load a url as a history navigation that will return an error. @@ -6541,7 +6512,7 @@ TestWillInsertBodyWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "clipped-body.html", false, + web_view_helper.InitializeAndLoad(base_url_ + "clipped-body.html", &web_frame_client); EXPECT_TRUE(web_frame_client.did_load_); @@ -6553,7 +6524,7 @@ TestWillInsertBodyWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(false, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); EXPECT_FALSE(web_frame_client.did_load_); // The empty document that a new frame starts with triggers this. @@ -6563,7 +6534,7 @@ TEST_P(ParameterizedWebFrameTest, MoveCaretSelectionTowardsWindowPointWithNoSelection) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true); + web_view_helper.InitializeAndLoad("about:blank"); WebFrame* frame = web_view_helper.WebView()->MainFrame(); // This test passes if this doesn't crash. @@ -6936,14 +6907,14 @@ TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentBody) { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); // Create another window that will try to access it. FrameTestHelpers::WebViewHelper new_web_view_helper; WebViewBase* new_view = new_web_view_helper.InitializeWithOpener( - web_view_helper.WebView()->MainFrame(), true); + web_view_helper.WebView()->MainFrame()); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -6959,14 +6930,14 @@ TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentOpen) { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); // Create another window that will try to access it. FrameTestHelpers::WebViewHelper new_web_view_helper; WebViewBase* new_view = new_web_view_helper.InitializeWithOpener( - web_view_helper.WebView()->MainFrame(), true); + web_view_helper.WebView()->MainFrame()); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -6983,14 +6954,14 @@ TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentNavigator) { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); // Create another window that will try to access it. FrameTestHelpers::WebViewHelper new_web_view_helper; WebViewBase* new_view = new_web_view_helper.InitializeWithOpener( - web_view_helper.WebView()->MainFrame(), true); + web_view_helper.WebView()->MainFrame()); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -7006,7 +6977,7 @@ TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentViaJavascriptUrl) { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -7023,14 +6994,14 @@ { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); // Create another window that will try to access it. FrameTestHelpers::WebViewHelper new_web_view_helper; WebViewBase* new_view = new_web_view_helper.InitializeWithOpener( - web_view_helper.WebView()->MainFrame(), true); + web_view_helper.WebView()->MainFrame()); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -7056,14 +7027,14 @@ { TestAccessInitialDocumentWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, &web_frame_client); + web_view_helper.Initialize(&web_frame_client); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); // Create another window that will try to access it. FrameTestHelpers::WebViewHelper new_web_view_helper; WebViewBase* new_view = new_web_view_helper.InitializeWithOpener( - web_view_helper.WebView()->MainFrame(), true); + web_view_helper.WebView()->MainFrame()); RunPendingTasks(); EXPECT_EQ(0, web_frame_client.did_access_initial_document_); @@ -7118,8 +7089,7 @@ // Make sure we initialize to minimum scale, even if the window size // only becomes available after the load begins. FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html", true, - &client); + web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html", &client); web_view_helper.Resize(WebSize(1000, 1000)); WebLocalFrameBase* frame_impl = web_view_helper.WebView()->MainFrameImpl(); @@ -7203,8 +7173,7 @@ redirect_url, final_response, file_path); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "first_party_redirect.html", - true); + web_view_helper.InitializeAndLoad(base_url_ + "first_party_redirect.html"); EXPECT_TRUE(web_view_helper.WebView() ->MainFrame() ->GetDocument() @@ -7226,7 +7195,7 @@ TestNavigationPolicyWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "fragment_middle_click.html", - true, &client); + &client); Document* document = ToLocalFrame(web_view_helper.WebView()->GetPage()->MainFrame()) @@ -7283,7 +7252,7 @@ TestNewWindowWebViewClient web_view_client; TestNewWindowWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "ctrl_click.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "ctrl_click.html", &web_frame_client, &web_view_client); Document* document = @@ -7316,8 +7285,7 @@ TEST_P(ParameterizedWebFrameTest, BackToReload) { RegisterMockedHttpURLLoad("fragment_middle_click.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fragment_middle_click.html", - true); + web_view_helper.InitializeAndLoad(base_url_ + "fragment_middle_click.html"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); const FrameLoader& main_frame_loader = web_view_helper.WebView()->MainFrameImpl()->GetFrame()->Loader(); @@ -7344,8 +7312,7 @@ TEST_P(ParameterizedWebFrameTest, BackDuringChildFrameReload) { RegisterMockedHttpURLLoad("page_with_blank_iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "page_with_blank_iframe.html", - true); + web_view_helper.InitializeAndLoad(base_url_ + "page_with_blank_iframe.html"); WebLocalFrameBase* main_frame = web_view_helper.LocalMainFrame(); const FrameLoader& main_frame_loader = main_frame->GetFrame()->Loader(); WebFrame* child_frame = main_frame->FirstChild(); @@ -7375,7 +7342,7 @@ TEST_P(ParameterizedWebFrameTest, ReloadPost) { RegisterMockedHttpURLLoad("reload_post.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "reload_post.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "reload_post.html"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), @@ -7397,8 +7364,7 @@ TEST_P(ParameterizedWebFrameTest, LoadHistoryItemReload) { RegisterMockedHttpURLLoad("fragment_middle_click.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "fragment_middle_click.html", - true); + web_view_helper.InitializeAndLoad(base_url_ + "fragment_middle_click.html"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); const FrameLoader& main_frame_loader = web_view_helper.WebView()->MainFrameImpl()->GetFrame()->Loader(); @@ -7464,7 +7430,7 @@ TestCachePolicyWebFrameClient main_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "iframe_reload.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "iframe_reload.html", &main_frame_client); WebLocalFrameBase* main_frame = web_view_helper.LocalMainFrame(); @@ -7524,7 +7490,7 @@ RegisterMockedHttpURLLoad("navigate_to_same.html"); TestSameDocumentWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "navigate_to_same.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "navigate_to_same.html", &client); EXPECT_FALSE(client.FrameLoadTypeReloadSeen()); @@ -7567,8 +7533,8 @@ RegisterMockedHttpURLLoad("white-1x1.png"); TestSameDocumentWithImageWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo_with_image.html", true, - &client, nullptr, nullptr, + web_view_helper.InitializeAndLoad(base_url_ + "foo_with_image.html", &client, + nullptr, nullptr, &ConfigureLoadsImagesAutomatically); WebCache::Clear(); @@ -7582,7 +7548,7 @@ TEST_P(ParameterizedWebFrameTest, WebNodeImageContents) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true); + web_view_helper.InitializeAndLoad("about:blank"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); static const char kBluePNG[] = @@ -7642,8 +7608,7 @@ RegisterMockedHttpURLLoad("push_state.html"); TestStartStopCallbackWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "push_state.html", true, - &client); + web_view_helper.InitializeAndLoad(base_url_ + "push_state.html", &client); EXPECT_EQ(client.StartLoadingCount(), 2); EXPECT_EQ(client.StopLoadingCount(), 2); @@ -7672,8 +7637,8 @@ RegisterMockedHttpURLLoad("push_state.html"); TestDidNavigateCommitTypeWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "push_state.html", true, &client); + WebViewBase* web_view_impl = + web_view_helper.InitializeAndLoad(base_url_ + "push_state.html", &client); Persistent<HistoryItem> item = ToLocalFrame(web_view_impl->GetPage()->MainFrame()) ->Loader() @@ -7730,7 +7695,7 @@ TestHistoryWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, &client); + web_view_helper.InitializeAndLoad("about:blank", &client); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); @@ -7759,7 +7724,7 @@ TestHistoryWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true, &client); + web_view_helper.InitializeAndLoad("about:blank", &client); WebFrame* frame = web_view_helper.WebView()->MainFrame(); @@ -7788,9 +7753,8 @@ fake_compositing_web_view_client = WTF::MakeUnique<FakeCompositingWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, - fake_compositing_web_view_client.get(), nullptr, - &ConfigureCompositingWebView); + web_view_helper.Initialize(nullptr, fake_compositing_web_view_client.get(), + nullptr, &ConfigureCompositingWebView); web_view_helper.Resize(WebSize(100, 100)); FrameTestHelpers::LoadFrame(web_view_helper.WebView()->MainFrame(), @@ -7866,7 +7830,7 @@ FailCreateChildFrame client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "create_child_frame_fail.html", - true, &client); + &client); EXPECT_EQ(1, client.CallCount()); } @@ -7875,8 +7839,8 @@ RegisterMockedHttpURLLoad("fixed-position-in-fixed-viewport.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "fixed-position-in-fixed-viewport.html", true, nullptr, - nullptr, nullptr, ConfigureAndroid); + base_url_ + "fixed-position-in-fixed-viewport.html", nullptr, nullptr, + nullptr, ConfigureAndroid); WebViewBase* web_view = web_view_helper.WebView(); web_view_helper.Resize(WebSize(100, 100)); @@ -7917,9 +7881,8 @@ FakeCompositingWebViewClient client; RegisterMockedHttpURLLoad("long_scroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html", true, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html", nullptr, + &client, nullptr, ConfigureAndroid); WebViewBase* web_view = web_view_helper.WebView(); LocalFrameView* frame_view = @@ -7996,7 +7959,7 @@ int viewport_height = 480; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "rtl-overview-mode.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "rtl-overview-mode.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.WebView()->SetInitialPageScaleOverride(-1); @@ -8020,7 +7983,7 @@ client.screen_info_.rect.width = viewport_width; client.screen_info_.rect.height = viewport_height; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_div.html", true, nullptr, &client, nullptr, + base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_impl->UpdateAllLifecyclePhases(); @@ -8063,7 +8026,7 @@ int viewport_width = 640; int viewport_height = 480; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_div.html", true, nullptr, &client, nullptr, + base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_impl->UpdateAllLifecyclePhases(); @@ -8119,7 +8082,7 @@ int viewport_width = 640; int viewport_height = 480; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_div.html", true, nullptr, &client, nullptr, + base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_impl->UpdateAllLifecyclePhases(); @@ -8177,7 +8140,7 @@ RegisterMockedHttpURLLoad("fullscreen_div.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_iframe.html", true, nullptr, &client, nullptr, + base_url_ + "fullscreen_iframe.html", nullptr, &client, nullptr, ConfigureAndroid); int viewport_width = 640; int viewport_height = 480; @@ -8217,8 +8180,8 @@ RegisterMockedHttpURLLoad("fullscreen_iframe.html"); RegisterMockedHttpURLLoad("fullscreen_div.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_iframe.html", true); + WebViewBase* web_view_impl = + web_view_helper.InitializeAndLoad(base_url_ + "fullscreen_iframe.html"); web_view_impl->UpdateAllLifecyclePhases(); @@ -8266,7 +8229,7 @@ RegisterMockedHttpURLLoad("viewport-tiny.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "viewport-tiny.html", true, nullptr, &client, nullptr, + base_url_ + "viewport-tiny.html", nullptr, &client, nullptr, ConfigureAndroid); int viewport_width = 384; int viewport_height = 640; @@ -8311,7 +8274,7 @@ RegisterMockedHttpURLLoad("viewport-tiny.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "viewport-tiny.html", true, nullptr, &client, nullptr, + base_url_ + "viewport-tiny.html", nullptr, &client, nullptr, ConfigureAndroid); int viewport_width = 384; int viewport_height = 640; @@ -8370,8 +8333,8 @@ RegisterMockedHttpURLLoad("fullscreen_restore_scale_factor.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_restore_scale_factor.html", true, nullptr, - &client, nullptr, &ConfigureAndroid); + base_url_ + "fullscreen_restore_scale_factor.html", nullptr, &client, + nullptr, &ConfigureAndroid); client.screen_info_.rect.width = screen_size_minus_status_bars_minus_url_bar.width; client.screen_info_.rect.height = @@ -8438,7 +8401,7 @@ int viewport_height = 200; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "viewport-tiny.html", true, nullptr, nullptr, nullptr, + base_url_ + "viewport-tiny.html", nullptr, nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); @@ -8514,7 +8477,7 @@ TestFullscreenWebViewClient web_view_client; FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "fullscreen_video.html", true, nullptr, &web_view_client); + base_url_ + "fullscreen_video.html", nullptr, &web_view_client); const TestFullscreenWebLayerTreeView& layer_tree_view = web_view_client.test_fullscreen_layer_tree_view; @@ -8618,7 +8581,7 @@ ManifestChangeWebFrameClient web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "link-manifest-change.html", - true, &web_frame_client); + &web_frame_client); EXPECT_EQ(14, web_frame_client.ManifestChangeCount()); } @@ -8699,7 +8662,7 @@ // policy of the request being set to ReloadBypassingCache. RegisterMockedHttpURLLoad("foo.html"); FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html"); WebLocalFrame* frame = web_view_helper.WebView()->MainFrameImpl(); FrameTestHelpers::ReloadFrameBypassingCache(frame); EXPECT_EQ(WebCachePolicy::kBypassingCache, @@ -8807,7 +8770,7 @@ RegisterMockedHttpURLLoad("theme_color_test.html"); ThemeColorTestWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "theme_color_test.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "theme_color_test.html", &client); EXPECT_TRUE(client.DidNotify()); WebLocalFrameBase* frame = web_view_helper.WebView()->MainFrameImpl(); @@ -8862,7 +8825,7 @@ RegisterMockedHttpURLLoad("subframe-c.html"); RegisterMockedHttpURLLoad("subframe-hello.html"); - web_view_helper_.InitializeAndLoad(base_url_ + "frame-a-b-c.html", true); + web_view_helper_.InitializeAndLoad(base_url_ + "frame-a-b-c.html"); } void Reset() { web_view_helper_.Reset(); } @@ -8964,7 +8927,7 @@ RegisterMockedHttpURLLoad("subframe-c.html"); RegisterMockedHttpURLLoad("subframe-hello.html"); - web_view_helper.InitializeAndLoad(base_url_ + "frame-a-b-c.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "frame-a-b-c.html", &frame_client); } @@ -9550,7 +9513,7 @@ TEST_F(WebFrameTest, WindowOpenRemoteClose) { FrameTestHelpers::WebViewHelper main_web_view; - main_web_view.Initialize(true); + main_web_view.Initialize(); // Create a remote window that will be closed later in the test. RemoteWindowCloseClient view_client; @@ -9582,7 +9545,7 @@ TEST_F(WebFrameTest, NavigateRemoteToLocalWithOpener) { FrameTestHelpers::WebViewHelper main_web_view; - main_web_view.Initialize(true); + main_web_view.Initialize(); WebFrame* main_frame = main_web_view.WebView()->MainFrame(); // Create a popup with a remote frame and set its opener to the main frame. @@ -9786,16 +9749,15 @@ FrameTestHelpers::WebViewHelper web_view_helper; TestConsoleMessageWebFrameClient web_frame_client; - FrameTestHelpers::TestWebViewClient web_view_client; - web_view_helper.InitializeAndLoad(base_url_ + "hidden_frames.html", true, - &web_frame_client, &web_view_client); + web_view_helper.InitializeAndLoad(base_url_ + "hidden_frames.html", + &web_frame_client); // Create another window with a cross-origin page, and point its opener to // first window. FrameTestHelpers::WebViewHelper popup_web_view_helper; TestConsoleMessageWebFrameClient popup_web_frame_client; WebViewBase* popup_view = popup_web_view_helper.InitializeAndLoad( - chrome_url_ + "hello_world.html", true, &popup_web_frame_client); + chrome_url_ + "hello_world.html", &popup_web_frame_client); popup_view->MainFrame()->SetOpener(web_view_helper.WebView()->MainFrame()); // Attempt a blocked navigation of an opener's subframe, and ensure that @@ -9832,7 +9794,7 @@ FixedLayoutTestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "device_media_queries.html", - true, nullptr, &client, nullptr, + nullptr, &client, nullptr, ConfigureAndroid); LocalFrame* frame = ToLocalFrame(web_view_helper.WebView()->GetPage()->MainFrame()); @@ -9882,7 +9844,7 @@ RegisterMockedHttpURLLoad("device_emulation.html"); client_.screen_info_.device_scale_factor = 1; web_view_helper_.InitializeAndLoad(base_url_ + "device_emulation.html", - true, 0, &client_); + nullptr, &client_); } void TestResize(const WebSize size, const String& expected_size) { @@ -10149,7 +10111,7 @@ RegisterMockedHttpURLLoad("overscroll/overscroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "overscroll/overscroll.html", - true, nullptr, &client, nullptr, + nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); @@ -10199,8 +10161,8 @@ RegisterMockedHttpURLLoad("overscroll/div-overscroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "overscroll/div-overscroll.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "overscroll/div-overscroll.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); ScrollBegin(&web_view_helper); @@ -10246,8 +10208,8 @@ RegisterMockedHttpURLLoad("overscroll/div-overscroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "overscroll/div-overscroll.html", true, nullptr, &client, - nullptr, ConfigureAndroid); + base_url_ + "overscroll/div-overscroll.html", nullptr, &client, nullptr, + ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); ScrollBegin(&web_view_helper); @@ -10273,7 +10235,7 @@ RegisterMockedHttpURLLoad("overscroll/scrollable-iframe.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad( - base_url_ + "overscroll/iframe-overscroll.html", true, nullptr, &client, + base_url_ + "overscroll/iframe-overscroll.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); @@ -10307,7 +10269,7 @@ RegisterMockedHttpURLLoad("overscroll/overscroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "overscroll/overscroll.html", true, nullptr, &client, nullptr, + base_url_ + "overscroll/overscroll.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); web_view_impl->SetPageScaleFactor(3.0); @@ -10349,7 +10311,7 @@ RegisterMockedHttpURLLoad("overscroll/overscroll.html"); FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad(base_url_ + "overscroll/overscroll.html", - true, nullptr, &client, nullptr, + nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(200, 200)); @@ -10408,15 +10370,15 @@ RegisterMockedHttpURLLoad("orientation-frame-detach.html"); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "orientation-frame-detach.html", true); + base_url_ + "orientation-frame-detach.html"); web_view_impl->MainFrameImpl()->SendOrientationChangeEvent(); } TEST_F(WebFrameTest, DISABLE_ON_TSAN(MaxFramesDetach)) { RegisterMockedHttpURLLoad("max-frames-detach.html"); FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.InitializeAndLoad( - base_url_ + "max-frames-detach.html", true); + WebViewBase* web_view_impl = + web_view_helper.InitializeAndLoad(base_url_ + "max-frames-detach.html"); web_view_impl->MainFrameImpl()->CollectGarbage(); } @@ -10480,7 +10442,7 @@ RegisterMockedHttpURLLoad("foo.html"); CallbackOrderingWebFrameClient client; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad(base_url_ + "foo.html", true, &client); + web_view_helper.InitializeAndLoad(base_url_ + "foo.html", &client); } class TestWebRemoteFrameClientForVisibility @@ -10500,9 +10462,9 @@ WebFrameVisibilityChangeTest() { RegisterMockedHttpURLLoad("visible_iframe.html"); RegisterMockedHttpURLLoad("single_iframe.html"); - frame_ = web_view_helper_ - .InitializeAndLoad(base_url_ + "single_iframe.html", true) - ->MainFrameImpl(); + frame_ = + web_view_helper_.InitializeAndLoad(base_url_ + "single_iframe.html") + ->MainFrameImpl(); web_remote_frame_ = RemoteFrameClient()->GetFrame(); } @@ -10559,7 +10521,7 @@ // global should never be reused on the initial navigation. TEST(WebFrameGlobalReuseTest, MainFrameWithNoOpener) { FrameTestHelpers::WebViewHelper helper; - helper.Initialize(true); + helper.Initialize(); WebLocalFrame* main_frame = helper.WebView()->MainFrameImpl(); v8::HandleScope scope(v8::Isolate::GetCurrent()); @@ -10575,7 +10537,7 @@ // injected script before the initial navigation. TEST(WebFrameGlobalReuseTest, ChildFrame) { FrameTestHelpers::WebViewHelper helper; - helper.Initialize(true, nullptr, nullptr, nullptr, + helper.Initialize(nullptr, nullptr, nullptr, EnableGlobalReuseForUnownedMainFrames); WebLocalFrame* main_frame = helper.WebView()->MainFrameImpl(); @@ -10596,10 +10558,10 @@ TEST(WebFrameGlobalReuseTest, MainFrameWithOpener) { FrameTestHelpers::TestWebViewClient opener_web_view_client; FrameTestHelpers::WebViewHelper opener_helper; - opener_helper.Initialize(false, nullptr, &opener_web_view_client, nullptr); + opener_helper.Initialize(nullptr, &opener_web_view_client, nullptr); FrameTestHelpers::WebViewHelper helper; - helper.InitializeWithOpener(opener_helper.WebView()->MainFrame(), true, - nullptr, nullptr, nullptr, + helper.InitializeWithOpener(opener_helper.WebView()->MainFrame(), nullptr, + nullptr, nullptr, EnableGlobalReuseForUnownedMainFrames); WebLocalFrame* main_frame = helper.WebView()->MainFrameImpl(); @@ -10618,7 +10580,7 @@ // to persist on the first navigation away from the initial empty document. TEST(WebFrameGlobalReuseTest, ReuseForMainFrameIfEnabled) { FrameTestHelpers::WebViewHelper helper; - helper.Initialize(true, nullptr, nullptr, nullptr, + helper.Initialize(nullptr, nullptr, nullptr, EnableGlobalReuseForUnownedMainFrames); WebLocalFrame* main_frame = helper.WebView()->MainFrameImpl(); @@ -10657,7 +10619,7 @@ FrameTestHelpers::WebViewHelper helper; SaveImageFromDataURLWebFrameClient client; - WebViewBase* web_view = helper.InitializeAndLoad(url, true, &client); + WebViewBase* web_view = helper.InitializeAndLoad(url, &client); web_view->Resize(WebSize(400, 400)); web_view->UpdateAllLifecyclePhases(); @@ -10694,7 +10656,7 @@ FrameTestHelpers::WebViewHelper helper; SaveImageFromDataURLWebFrameClient client; - WebViewBase* web_view = helper.InitializeAndLoad(url, true, &client); + WebViewBase* web_view = helper.InitializeAndLoad(url, &client); web_view->Resize(WebSize(400, 400)); WebLocalFrame* local_frame = web_view->MainFrameImpl(); @@ -10726,7 +10688,7 @@ RegisterMockedURLLoadFromBase(base_url_, "canvas-copy-image.html"); FrameTestHelpers::WebViewHelper helper; - WebViewBase* web_view = helper.InitializeAndLoad(url, true, 0); + WebViewBase* web_view = helper.InitializeAndLoad(url); web_view->Resize(WebSize(400, 400)); uint64_t sequence = Platform::Current()->Clipboard()->SequenceNumber( @@ -10750,7 +10712,7 @@ RegisterMockedURLLoadFromBase(base_url_, "canvas-copy-image.html"); FrameTestHelpers::WebViewHelper helper; - WebViewBase* web_view = helper.InitializeAndLoad(url, true, 0); + WebViewBase* web_view = helper.InitializeAndLoad(url); web_view->Resize(WebSize(400, 400)); web_view->UpdateAllLifecyclePhases(); web_view->SetPageScaleFactor(2); @@ -10779,7 +10741,7 @@ RegisterMockedURLLoadFromBase(base_url_, "image-map.html"); FrameTestHelpers::WebViewHelper helper; - WebViewBase* web_view = helper.InitializeAndLoad(url, true, &client); + WebViewBase* web_view = helper.InitializeAndLoad(url, &client); web_view->Resize(WebSize(400, 400)); client.Reset(); @@ -10806,7 +10768,7 @@ TEST_F(WebFrameTest, LoadJavascriptURLInNewFrame) { FrameTestHelpers::WebViewHelper helper; - helper.Initialize(true); + helper.Initialize(); std::string redirect_url = base_url_ + "foo.html"; URLTestHelpers::RegisterMockedURLLoad(ToKURL(redirect_url), @@ -10874,7 +10836,7 @@ WebURLRequest::kPriorityLow); FrameTestHelpers::WebViewHelper helper; - helper.Initialize(true, &client); + helper.Initialize(&client); helper.Resize(WebSize(640, 480)); FrameTestHelpers::LoadFrame( helper.WebView()->MainFrame(), @@ -10924,7 +10886,7 @@ WebURLRequest::kPriorityHigh); FrameTestHelpers::WebViewHelper helper; - helper.InitializeAndLoad(base_url_ + "script_priority.html", true, &client); + helper.InitializeAndLoad(base_url_ + "script_priority.html", &client); client.VerifyAllRequests(); } @@ -10948,7 +10910,7 @@ MultipleDataChunkDelegate delegate; Platform::Current()->GetURLLoaderMockFactory()->SetLoaderDelegate(&delegate); FrameTestHelpers::WebViewHelper helper; - helper.InitializeAndLoad(url, true); + helper.InitializeAndLoad(url); Platform::Current()->GetURLLoaderMockFactory()->SetLoaderDelegate(nullptr); Document* document = @@ -10967,7 +10929,7 @@ constexpr int kBrowserControlsHeight = 100; FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, nullptr, nullptr, ConfigureAndroid); + web_view_helper.Initialize(nullptr, nullptr, nullptr, ConfigureAndroid); WebViewBase* web_view = web_view_helper.WebView(); web_view->ResizeWithBrowserControls( WebSize(kViewportWidth, kViewportHeight - kBrowserControlsHeight), @@ -11072,7 +11034,7 @@ TEST_F(WebFrameTest, HidingScrollbarsOnScrollableAreaDisablesScrollbars) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true); + web_view_helper.Initialize(); web_view_helper.Resize(WebSize(800, 600)); WebViewBase* web_view = web_view_helper.WebView(); @@ -11133,7 +11095,7 @@ TEST_F(WebFrameTest, MouseOverDifferntNodeClearsTooltip) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, nullptr, nullptr, + web_view_helper.Initialize(nullptr, nullptr, nullptr, [](WebSettings* settings) {}); web_view_helper.Resize(WebSize(200, 200)); WebViewBase* web_view = web_view_helper.WebView(); @@ -11213,7 +11175,7 @@ // scrollbar is faded out. TEST_F(WebFrameTest, MouseOverLinkAndOverlayScrollbar) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.Initialize(true, nullptr, nullptr, nullptr, + web_view_helper.Initialize(nullptr, nullptr, nullptr, [](WebSettings* settings) {}); web_view_helper.Resize(WebSize(20, 20)); WebViewBase* web_view = web_view_helper.WebView(); @@ -11660,9 +11622,8 @@ FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view; if (viewport_enabled) { - web_view = web_view_helper.InitializeAndLoad(base_url_ + test_page, false, - nullptr, &client, nullptr, - ConfigureAndroid); + web_view = web_view_helper.InitializeAndLoad( + base_url_ + test_page, nullptr, &client, nullptr, ConfigureAndroid); } else { web_view = web_view_helper.InitializeAndLoad(base_url_ + test_page); } @@ -11741,7 +11702,7 @@ TEST_F(WebFrameTest, DISABLE_ON_TSAN(TestNonCompositedOverlayScrollbarsFade)) { FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, nullptr, nullptr, &DisableCompositing); + nullptr, nullptr, nullptr, &DisableCompositing); constexpr double kMockOverlayFadeOutDelayMs = 5.0; @@ -12007,7 +11968,7 @@ FrameTestHelpers::WebViewHelper web_view_helper; MainFrameClient main_frame_client; - web_view_helper.InitializeAndLoad(base_url_ + "single_iframe.html", true, + web_view_helper.InitializeAndLoad(base_url_ + "single_iframe.html", &main_frame_client); EXPECT_TRUE(main_frame_client.ChildClient().DidCallFrameDetached()); @@ -12019,9 +11980,8 @@ } TEST_F(WebFrameTest, ClearClosedOpener) { - FrameTestHelpers::TestWebViewClient opener_web_view_client; FrameTestHelpers::WebViewHelper opener_helper; - opener_helper.Initialize(false, nullptr, &opener_web_view_client); + opener_helper.Initialize(); FrameTestHelpers::WebViewHelper helper; helper.InitializeWithOpener(opener_helper.WebView()->MainFrame()); @@ -12047,7 +12007,7 @@ TEST_F(WebFrameTest, ShowVirtualKeyboardOnElementFocus) { FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view = web_view_helper.Initialize(true); + WebViewBase* web_view = web_view_helper.Initialize(); WebRemoteFrameImpl* remote_frame = static_cast<WebRemoteFrameImpl*>( WebRemoteFrame::Create(WebTreeScopeType::kDocument, nullptr)); web_view->SetMainFrame(remote_frame); @@ -12095,7 +12055,7 @@ bool TestSelectAll(const std::string& html) { ContextMenuWebFrameClient frame; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view = web_view_helper.Initialize(true, &frame); + WebViewBase* web_view = web_view_helper.Initialize(&frame); FrameTestHelpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); web_view->Resize(WebSize(500, 300)); @@ -12130,7 +12090,7 @@ TEST_F(WebFrameTest, ContextMenuDataSelectedText) { ContextMenuWebFrameClient frame; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view = web_view_helper.Initialize(true, &frame); + WebViewBase* web_view = web_view_helper.Initialize(&frame); const std::string& html = "<input value=' '>"; FrameTestHelpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); @@ -12212,7 +12172,7 @@ main_client.SetChildWebFrameClient(&child_client); FrameTestHelpers::WebViewHelper web_view_helper_; - web_view_helper_.Initialize(true, &main_client); + web_view_helper_.Initialize(&main_client); WebLocalFrameBase* main_frame = web_view_helper_.WebView()->MainFrameImpl(); WebURLRequest request(ToKURL(base_url_ + "fallback.html")); @@ -12237,7 +12197,7 @@ TEST_F(WebFrameTest, AltTextOnAboutBlankPage) { FrameTestHelpers::WebViewHelper web_view_helper; - web_view_helper.InitializeAndLoad("about:blank", true); + web_view_helper.InitializeAndLoad("about:blank"); web_view_helper.Resize(WebSize(640, 480)); WebLocalFrameBase* frame = web_view_helper.WebView()->MainFrameImpl();
diff --git a/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp b/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp index df5048f..eeea020 100644 --- a/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebHelperPluginTest.cpp
@@ -45,7 +45,7 @@ class WebHelperPluginTest : public ::testing::Test { protected: void SetUp() override { - helper_.InitializeAndLoad("about:blank", false, &frame_client_); + helper_.InitializeAndLoad("about:blank", &frame_client_); } void DestroyHelperPlugin() {
diff --git a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp index 40ca4a4..bd885d48 100644 --- a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp
@@ -120,7 +120,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); web_view->GetSettings()->SetViewportEnabled(true); int page_width = 640; int page_height = 480; @@ -347,7 +347,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); web_view->GetSettings()->SetViewportEnabled(true); int page_width = 640; int page_height = 480; @@ -618,7 +618,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); @@ -657,7 +657,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); @@ -758,7 +758,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); @@ -834,7 +834,7 @@ RegisterMockedURL(base_url, file_name); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = - web_view_helper.InitializeAndLoad(base_url + file_name, true); + web_view_helper.InitializeAndLoad(base_url + file_name); int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height));
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp index 9c116b71..81092e6 100644 --- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -180,7 +180,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -219,7 +219,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "test.pdf", true, &plugin_web_frame_client); + base_url_ + "test.pdf", &plugin_web_frame_client); DCHECK(web_view); web_view->UpdateAllLifecyclePhases(); @@ -238,7 +238,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "iframe_pdf.html", true, &plugin_web_frame_client); + base_url_ + "iframe_pdf.html", &plugin_web_frame_client); DCHECK(web_view); web_view->UpdateAllLifecyclePhases(); @@ -259,7 +259,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "test.pdf", true, &plugin_web_frame_client); + base_url_ + "test.pdf", &plugin_web_frame_client); DCHECK(web_view); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -283,7 +283,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "test.pdf", true, &plugin_web_frame_client); + base_url_ + "test.pdf", &plugin_web_frame_client); DCHECK(web_view); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -306,7 +306,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -344,7 +344,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -368,7 +368,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -411,7 +411,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -508,7 +508,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -557,7 +557,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -593,7 +593,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -635,7 +635,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -693,7 +693,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -734,7 +734,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -774,7 +774,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -815,7 +815,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -857,7 +857,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_scroll.html", true, &plugin_web_frame_client); + base_url_ + "plugin_scroll.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -902,7 +902,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -940,8 +940,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_containing_page.html", true, - &plugin_web_frame_client); + base_url_ + "plugin_containing_page.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -974,7 +973,7 @@ plugin_web_frame_client; // Must outlive webViewHelper. FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -1023,7 +1022,7 @@ CustomPluginWebFrameClient<TopmostPlugin> plugin_web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300)); @@ -1083,7 +1082,7 @@ CustomPluginWebFrameClient<CompositedPlugin> web_frame_client; FrameTestHelpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin.html", true, &web_frame_client); + base_url_ + "plugin.html", &web_frame_client); ASSERT_TRUE(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(800, 600)); @@ -1125,7 +1124,7 @@ plugin_web_frame_client; // Must outlive webViewHelper FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view = web_view_helper.InitializeAndLoad( - base_url_ + "plugin_container.html", true, &plugin_web_frame_client); + base_url_ + "plugin_container.html", &plugin_web_frame_client); DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->Resize(WebSize(300, 300));
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index 25c4c42..b53d750b 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -287,7 +287,7 @@ // Test that hit tests on parts of a video element result in hits on the video // element itself as opposed to its child elements. std::string url = RegisterMockedHttpURLLoad("video_200x200.html"); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true, 0); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); web_view->Resize(WebSize(200, 200)); // Center of video. @@ -303,7 +303,7 @@ TEST_P(WebViewTest, HitTestContentEditableImageMaps) { std::string url = RegisterMockedHttpURLLoad("content-editable-image-maps.html"); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true, 0); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); web_view->Resize(WebSize(500, 500)); EXPECT_EQ("areaANotEditable", HitTestElementId(web_view, 25, 25)); @@ -341,7 +341,7 @@ TEST_P(WebViewTest, ImageMapUrls) { std::string url = RegisterMockedHttpURLLoad("image-map.html"); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true, 0); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); web_view->Resize(WebSize(400, 400)); std::string image_url = @@ -557,7 +557,7 @@ std::string url = base_url_ + "specify_size.html?" + "50px" + ":" + "50px"; URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true, 0); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); web_view->Resize(WebSize(100, 100)); WebPoint hit_point(75, 75); @@ -578,7 +578,7 @@ std::string url = base_url_ + "specify_size.html?" + "50px" + ":" + "50px"; URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); - WebView* web_view = web_view_helper_.Initialize(true); + WebView* web_view = web_view_helper_.Initialize(); LoadFrame(web_view->MainFrame(), url); web_view->Resize(WebSize(100, 100)); WebPoint hit_point(75, 75); @@ -605,7 +605,7 @@ TEST_P(WebViewTest, HitTestResultForTapWithTapArea) { std::string url = RegisterMockedHttpURLLoad("hit_test.html"); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true, 0); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); web_view->Resize(WebSize(100, 100)); WebPoint hit_point(55, 55); @@ -633,7 +633,7 @@ TEST_P(WebViewTest, HitTestResultForTapWithTapAreaPageScaleAndPan) { std::string url = RegisterMockedHttpURLLoad("hit_test.html"); - WebView* web_view = web_view_helper_.Initialize(true); + WebView* web_view = web_view_helper_.Initialize(); LoadFrame(web_view->MainFrame(), url); web_view->Resize(WebSize(100, 100)); WebPoint hit_point(55, 55); @@ -676,7 +676,7 @@ URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); WebViewBase* web_view = - web_view_helper_.InitializeAndLoad(url, true, 0, &client); + web_view_helper_.InitializeAndLoad(url, nullptr, &client); client.GetTestData().SetWebView(web_view); WebLocalFrameBase* frame = web_view->MainFrameImpl(); @@ -809,9 +809,8 @@ } TEST_P(WebViewTest, TextInputInfoUpdateStyleAndLayout) { - FrameTestHelpers::TestWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.Initialize(true, 0, &client); + WebViewBase* web_view_impl = web_view_helper.Initialize(); WebURL base_url = URLTestHelpers::ToKURL("http://example.com/"); // Here, we need to construct a document that has a special property: @@ -1920,7 +1919,7 @@ PrintWebViewClient client; RegisterMockedHttpURLLoad("print_with_xhr_inflight.html"); WebViewBase* web_view_impl = web_view_helper_.InitializeAndLoad( - base_url_ + "print_with_xhr_inflight.html", true, 0, &client); + base_url_ + "print_with_xhr_inflight.html", nullptr, &client); ASSERT_TRUE(ToLocalFrame(web_view_impl->GetPage()->MainFrame()) ->GetDocument() @@ -2030,9 +2029,8 @@ TEST_P(WebViewTest, ClientTapHandling) { TapHandlingWebViewClient client; - client.Reset(); WebView* web_view = - web_view_helper_.InitializeAndLoad("about:blank", true, 0, &client); + web_view_helper_.InitializeAndLoad("about:blank", nullptr, &client); WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers, WebInputEvent::kTimeStampForTesting); event.source_device = kWebGestureDeviceTouchscreen; @@ -2085,7 +2083,7 @@ RegisterMockedHttpURLLoad("long_press_empty_div.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_empty_div.html", true); + base_url_ + "long_press_empty_div.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(false); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2106,7 +2104,7 @@ RegisterMockedHttpURLLoad("long_press_empty_div.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_empty_div.html", true); + base_url_ + "long_press_empty_div.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(true); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2126,8 +2124,8 @@ TEST_P(WebViewTest, LongPressObject) { RegisterMockedHttpURLLoad("long_press_object.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_object.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "long_press_object.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(true); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2152,7 +2150,7 @@ RegisterMockedHttpURLLoad("long_press_object_fallback.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_object_fallback.html", true); + base_url_ + "long_press_object_fallback.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(true); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2176,8 +2174,8 @@ TEST_P(WebViewTest, LongPressImage) { RegisterMockedHttpURLLoad("long_press_image.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_image.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "long_press_image.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(false); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2197,8 +2195,8 @@ TEST_P(WebViewTest, LongPressVideo) { RegisterMockedHttpURLLoad("long_press_video.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_video.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "long_press_video.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(false); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2218,8 +2216,8 @@ TEST_P(WebViewTest, LongPressLink) { RegisterMockedHttpURLLoad("long_press_link.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_link.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "long_press_link.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(false); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2243,7 +2241,7 @@ ToKURL("http://www.test.com/foo.png"), testing::WebTestDataPath("white-1x1.png")); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_links_and_images.html", true); + base_url_ + "long_press_links_and_images.html"); web_view->SettingsImpl()->SetTouchDragDropEnabled(true); web_view->Resize(WebSize(500, 300)); @@ -2266,7 +2264,7 @@ RegisterMockedHttpURLLoad("long_press_empty_editable_selection.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_empty_editable_selection.html", true); + base_url_ + "long_press_empty_editable_selection.html"); web_view->SettingsImpl()->SetAlwaysShowContextMenuOnTouch(false); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); @@ -2286,8 +2284,8 @@ TEST_P(WebViewTest, LongPressEmptyNonEditableSelection) { RegisterMockedHttpURLLoad("long_press_image.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "long_press_image.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "long_press_image.html"); web_view->Resize(WebSize(500, 500)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2309,7 +2307,7 @@ RegisterMockedHttpURLLoad("longpress_selection.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "longpress_selection.html", true); + base_url_ + "longpress_selection.html"); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2329,7 +2327,7 @@ RegisterMockedHttpURLLoad("longpress_selection.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "longpress_selection.html", true); + base_url_ + "longpress_selection.html"); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2364,8 +2362,8 @@ TEST_P(WebViewTest, TouchDoesntSelectEmptyTextarea) { RegisterMockedHttpURLLoad("longpress_textarea.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "longpress_textarea.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "longpress_textarea.html"); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2408,7 +2406,7 @@ RegisterMockedHttpURLLoad("longpress_image_contenteditable.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "longpress_image_contenteditable.html", true); + base_url_ + "longpress_image_contenteditable.html"); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2426,7 +2424,7 @@ RegisterMockedHttpURLLoad("blink_caret_on_typing_after_long_press.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "blink_caret_on_typing_after_long_press.html", true); + base_url_ + "blink_caret_on_typing_after_long_press.html"); web_view->Resize(WebSize(640, 480)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2441,7 +2439,7 @@ TEST_P(WebViewTest, BlinkCaretOnClosingContextMenu) { RegisterMockedHttpURLLoad("form.html"); WebViewBase* web_view = - web_view_helper_.InitializeAndLoad(base_url_ + "form.html", true); + web_view_helper_.InitializeAndLoad(base_url_ + "form.html"); web_view->SetInitialFocus(false); RunPendingTasks(); @@ -2474,8 +2472,8 @@ TEST_P(WebViewTest, SelectionOnReadOnlyInput) { RegisterMockedHttpURLLoad("selection_readonly.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "selection_readonly.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "selection_readonly.html"); web_view->Resize(WebSize(640, 480)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2494,8 +2492,8 @@ TEST_P(WebViewTest, KeyDownScrollsHandled) { RegisterMockedHttpURLLoad("content-width-1000.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "content-width-1000.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "content-width-1000.html"); web_view->Resize(WebSize(100, 100)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -2590,13 +2588,9 @@ } TEST_P(WebViewTest, ShowPressOnTransformedLink) { - std::unique_ptr<FrameTestHelpers::TestWebViewClient> - fake_compositing_web_view_client = - WTF::MakeUnique<FrameTestHelpers::TestWebViewClient>(); FrameTestHelpers::WebViewHelper web_view_helper; WebViewBase* web_view_impl = web_view_helper.Initialize( - true, nullptr, fake_compositing_web_view_client.get(), nullptr, - &ConfigueCompositingWebView); + nullptr, nullptr, nullptr, &ConfigueCompositingWebView); int page_width = 640; int page_height = 480; @@ -2786,7 +2780,7 @@ RegisterMockedHttpURLLoad("input_field_populated.html"); MockAutofillClient client; WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "input_field_populated.html", true); + base_url_ + "input_field_populated.html"); WebLocalFrameBase* frame = web_view->MainFrameImpl(); frame->SetAutofillClient(&client); web_view->SetInitialFocus(false); @@ -2822,7 +2816,7 @@ const WebString& name, WebNavigationPolicy, bool) override { - return web_view_helper_.InitializeWithOpener(opener, true); + return web_view_helper_.InitializeWithOpener(opener); } // WebWidgetClient methods @@ -2839,7 +2833,7 @@ TEST_P(WebViewTest, DoNotFocusCurrentFrameOnNavigateFromLocalFrame) { ViewCreatingWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.Initialize(true, 0, &client); + WebViewBase* web_view_impl = web_view_helper.Initialize(nullptr, &client); WebURL base_url = URLTestHelpers::ToKURL("http://example.com/"); FrameTestHelpers::LoadHTMLString( @@ -2863,7 +2857,7 @@ TEST_P(WebViewTest, FocusExistingFrameOnNavigate) { ViewCreatingWebViewClient client; FrameTestHelpers::WebViewHelper web_view_helper; - WebViewBase* web_view_impl = web_view_helper.Initialize(true, 0, &client); + WebViewBase* web_view_impl = web_view_helper.Initialize(nullptr, &client); WebLocalFrameBase* frame = web_view_impl->MainFrameImpl(); frame->SetName("_start"); @@ -2892,7 +2886,7 @@ TEST_P(WebViewTest, DispatchesFocusOutFocusInOnViewToggleFocus) { RegisterMockedHttpURLLoad("focusout_focusin_events.html"); WebView* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "focusout_focusin_events.html", true, 0); + base_url_ + "focusout_focusin_events.html"); web_view->SetFocus(true); web_view->SetFocus(false); @@ -2906,7 +2900,7 @@ TEST_P(WebViewTest, DispatchesDomFocusOutDomFocusInOnViewToggleFocus) { RegisterMockedHttpURLLoad("domfocusout_domfocusin_events.html"); WebView* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "domfocusout_domfocusin_events.html", true, 0); + base_url_ + "domfocusout_domfocusin_events.html"); web_view->SetFocus(true); web_view->SetFocus(false); @@ -2944,7 +2938,7 @@ DateTimeChooserWebViewClient client; std::string url = RegisterMockedHttpURLLoad("date_time_chooser.html"); WebViewBase* web_view_impl = - web_view_helper_.InitializeAndLoad(url, true, 0, &client); + web_view_helper_.InitializeAndLoad(url, nullptr, &client); Document* document = web_view_impl->MainFrameImpl()->GetFrame()->GetDocument(); @@ -3020,8 +3014,8 @@ TEST_P(WebViewTest, DispatchesFocusBlurOnViewToggle) { RegisterMockedHttpURLLoad("focus_blur_events.html"); - WebView* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "focus_blur_events.html", true, 0); + WebView* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "focus_blur_events.html"); web_view->SetFocus(true); web_view->SetFocus(false); @@ -3174,7 +3168,7 @@ TEST_P(WebViewTest, ChangeDisplayMode) { RegisterMockedHttpURLLoad("display_mode.html"); WebView* web_view = - web_view_helper_.InitializeAndLoad(base_url_ + "display_mode.html", true); + web_view_helper_.InitializeAndLoad(base_url_ + "display_mode.html"); std::string content = WebFrameContentDumper::DumpWebViewAsText(web_view, 21).Utf8(); @@ -3190,7 +3184,7 @@ CreateChildCounterFrameClient frame_client; RegisterMockedHttpURLLoad("add_frame_in_unload.html"); web_view_helper_.InitializeAndLoad(base_url_ + "add_frame_in_unload.html", - true, &frame_client); + &frame_client); web_view_helper_.Reset(); EXPECT_EQ(0, frame_client.Count()); } @@ -3199,7 +3193,7 @@ CreateChildCounterFrameClient frame_client; RegisterMockedHttpURLLoad("add_frame_in_unload.html"); web_view_helper_.InitializeAndLoad(base_url_ + "add_frame_in_unload.html", - true, &frame_client); + &frame_client); web_view_helper_.WebView()->MainFrameImpl()->DispatchUnloadEvent(); EXPECT_EQ(0, frame_client.Count()); web_view_helper_.Reset(); @@ -3209,7 +3203,7 @@ CreateChildCounterFrameClient frame_client; RegisterMockedHttpURLLoad("add_frame_in_unload.html"); web_view_helper_.InitializeAndLoad(base_url_ + "add_frame_in_unload.html", - true, &frame_client); + &frame_client); FrameTestHelpers::LoadFrame(web_view_helper_.WebView()->MainFrame(), "about:blank"); EXPECT_EQ(0, frame_client.Count()); @@ -3221,7 +3215,7 @@ RegisterMockedHttpURLLoad("add_frame_in_unload_wrapper.html"); RegisterMockedHttpURLLoad("add_frame_in_unload.html"); web_view_helper_.InitializeAndLoad( - base_url_ + "add_frame_in_unload_wrapper.html", true, &frame_client); + base_url_ + "add_frame_in_unload_wrapper.html", &frame_client); FrameTestHelpers::LoadFrame(web_view_helper_.WebView()->MainFrame(), "about:blank"); EXPECT_EQ(1, frame_client.Count()); @@ -3260,7 +3254,7 @@ WebLayerTreeView* layer_tree_view = client.InitializeLayerTreeView(); std::string url = RegisterMockedHttpURLLoad("has_touch_event_handlers.html"); WebViewBase* web_view_impl = - web_view_helper_.InitializeAndLoad(url, true, 0, 0, &client); + web_view_helper_.InitializeAndLoad(url, nullptr, nullptr, &client); ASSERT_TRUE(layer_tree_view); const EventHandlerRegistry::EventHandlerClass kTouchEvent = EventHandlerRegistry::kTouchStartOrMoveEventBlocking; @@ -3387,7 +3381,7 @@ // by layout tests under fast/events/. TEST_P(WebViewTest, DeleteElementWithRegisteredHandler) { std::string url = RegisterMockedHttpURLLoad("simple_div.html"); - WebViewBase* web_view_impl = web_view_helper_.InitializeAndLoad(url, true); + WebViewBase* web_view_impl = web_view_helper_.InitializeAndLoad(url); Persistent<Document> document = web_view_impl->MainFrameImpl()->GetFrame()->GetDocument(); @@ -3413,7 +3407,7 @@ // This test verifies the text input flags are correctly exposed to script. TEST_P(WebViewTest, TextInputFlags) { std::string url = RegisterMockedHttpURLLoad("text_input_flags.html"); - WebViewBase* web_view_impl = web_view_helper_.InitializeAndLoad(url, true); + WebViewBase* web_view_impl = web_view_helper_.InitializeAndLoad(url); web_view_impl->SetInitialFocus(false); WebLocalFrameBase* frame = web_view_impl->MainFrameImpl(); @@ -3474,7 +3468,7 @@ RegisterMockedHttpURLLoad("form.html"); MockAutofillClient client; WebViewBase* web_view = - web_view_helper_.InitializeAndLoad(base_url_ + "form.html", true); + web_view_helper_.InitializeAndLoad(base_url_ + "form.html"); WebLocalFrameBase* frame = web_view->MainFrameImpl(); frame->SetAutofillClient(&client); web_view->SetInitialFocus(false); @@ -3498,7 +3492,7 @@ RegisterMockedHttpURLLoad("form.html"); MockAutofillClient client; WebViewBase* web_view = - web_view_helper_.InitializeAndLoad(base_url_ + "form.html", true); + web_view_helper_.InitializeAndLoad(base_url_ + "form.html"); WebLocalFrameBase* frame = web_view->MainFrameImpl(); frame->SetAutofillClient(&client); web_view->SetInitialFocus(false); @@ -3542,7 +3536,7 @@ TEST_P(WebViewTest, CompareSelectAllToContentAsText) { RegisterMockedHttpURLLoad("longpress_selection.html"); WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "longpress_selection.html", true); + base_url_ + "longpress_selection.html"); WebLocalFrameBase* frame = web_view->MainFrameImpl(); frame->ExecuteScript(WebScriptSource( @@ -3558,7 +3552,7 @@ TEST_P(WebViewTest, AutoResizeSubtreeLayout) { std::string url = RegisterMockedHttpURLLoad("subtree-layout.html"); - WebView* web_view = web_view_helper_.Initialize(true); + WebView* web_view = web_view_helper_.Initialize(); web_view->EnableAutoResizeMode(WebSize(200, 200), WebSize(200, 200)); LoadFrame(web_view->MainFrame(), url); @@ -3576,7 +3570,7 @@ std::string url = base_url_ + "specify_size.html?100px:100px"; URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); WebSize size = web_view->ContentsPreferredMinimumSize(); EXPECT_EQ(100, size.width); @@ -3602,7 +3596,7 @@ url = base_url_ + "specify_size.html?1.5px:1.5px"; URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); - web_view = web_view_helper_.InitializeAndLoad(url, true); + web_view = web_view_helper_.InitializeAndLoad(url); web_view->SetZoomLevel(WebView::ZoomFactorToZoomLevel(1)); size = web_view->ContentsPreferredMinimumSize(); @@ -3614,7 +3608,7 @@ std::string url = base_url_ + "specify_size.html?100px:100px"; URLTestHelpers::RegisterMockedURLLoad( ToKURL(url), testing::WebTestDataPath("specify_size.html")); - WebView* web_view = web_view_helper_.InitializeAndLoad(url, true); + WebView* web_view = web_view_helper_.InitializeAndLoad(url); WebElement document_element = web_view->MainFrame()->GetDocument().DocumentElement(); @@ -3665,7 +3659,7 @@ RegisterMockedHttpURLLoad(test_file); UnhandledTapWebViewClient client; WebView* web_view = web_view_helper_.InitializeAndLoad(base_url_ + test_file, - true, 0, &client); + nullptr, &client); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -3734,7 +3728,7 @@ RegisterMockedHttpURLLoad(test_file); UnhandledTapWebViewClient client; WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + test_file, true, 0, &client); + base_url_ + test_file, nullptr, &client); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -3759,7 +3753,7 @@ RegisterMockedHttpURLLoad(test_file); UnhandledTapWebViewClient client; WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + test_file, true, 0, &client); + base_url_ + test_file, nullptr, &client); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -3793,7 +3787,7 @@ RegisterMockedHttpURLLoad(test_file); UnhandledTapWebViewClient client; WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + test_file, true, 0, &client); + base_url_ + test_file, nullptr, &client); web_view->Resize(WebSize(500, 300)); web_view->UpdateAllLifecyclePhases(); RunPendingTasks(); @@ -3815,7 +3809,7 @@ TEST_P(WebViewTest, StopLoadingIfJavaScriptURLReturnsNoStringResult) { ViewCreatingWebViewClient client; FrameTestHelpers::WebViewHelper main_web_view; - main_web_view.InitializeAndLoad("about:blank", true, 0, &client); + main_web_view.InitializeAndLoad("about:blank", nullptr, &client); WebLocalFrame* frame = main_web_view.WebView()->MainFrameImpl(); v8::HandleScope scope(v8::Isolate::GetCurrent()); @@ -3929,7 +3923,7 @@ RegisterMockedHttpURLLoad("input_field_password.html"); MockAutofillClient client; WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "input_field_password.html", true); + base_url_ + "input_field_password.html"); WebLocalFrameBase* frame = web_view->MainFrameImpl(); frame->SetAutofillClient(&client); web_view->SetInitialFocus(false); @@ -3965,8 +3959,8 @@ TEST_P(WebViewTest, SubframeBeforeUnloadUseCounter) { RegisterMockedHttpURLLoad("visible_iframe.html"); RegisterMockedHttpURLLoad("single_iframe.html"); - WebViewBase* web_view = web_view_helper_.InitializeAndLoad( - base_url_ + "single_iframe.html", true); + WebViewBase* web_view = + web_view_helper_.InitializeAndLoad(base_url_ + "single_iframe.html"); WebLocalFrame* frame = web_view_helper_.WebView()->MainFrameImpl(); Document* document =
diff --git a/third_party/WebKit/Source/web/tests/data/input_field_populated.html b/third_party/WebKit/Source/web/tests/data/input_field_populated.html index ba540cb..3f20180d 100644 --- a/third_party/WebKit/Source/web/tests/data/input_field_populated.html +++ b/third_party/WebKit/Source/web/tests/data/input_field_populated.html
@@ -2,9 +2,3 @@ <div id="inputEvent">none</div> <!- "ab" + trophy + space + "cdef" + trophy + space + "gh"> <input id="sample2" value='ab🏆 cdef🏆 gh'/> -<script> -document.getElementById('sample').addEventListener('input', function() { - document.getElementById('inputEvent').textContent = 'got'; -}); -</script> -
diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h index 3db02d3e..394d190b 100644 --- a/third_party/WebKit/public/web/WebFrame.h +++ b/third_party/WebKit/public/web/WebFrame.h
@@ -153,9 +153,6 @@ // Returns the visible content rect (minus scrollbars, in absolute coordinate) virtual WebRect VisibleContentRect() const = 0; - virtual bool HasHorizontalScrollbar() const = 0; - virtual bool HasVerticalScrollbar() const = 0; - // Whether to collapse the frame's owner element in the embedder document, // that is, to remove it from the layout as if it did not exist. Only works // for <iframe> owner elements.
diff --git a/third_party/WebKit/public/web/WebWidgetClient.h b/third_party/WebKit/public/web/WebWidgetClient.h index c948511..cd56c11 100644 --- a/third_party/WebKit/public/web/WebWidgetClient.h +++ b/third_party/WebKit/public/web/WebWidgetClient.h
@@ -84,6 +84,10 @@ // Called when the cursor for the widget changes. virtual void DidChangeCursor(const WebCursorInfo&) {} + virtual void AutoscrollStart(const WebFloatPoint&) {} + virtual void AutoscrollFling(const WebFloatSize& velocity) {} + virtual void AutoscrollEnd() {} + // Called when the widget should be closed. WebWidget::close() should // be called asynchronously as a result of this notification. virtual void CloseWidgetSoon() {}
diff --git a/third_party/closure_compiler/README.chromium b/third_party/closure_compiler/README.chromium index c4a320f41..1272225 100644 --- a/third_party/closure_compiler/README.chromium +++ b/third_party/closure_compiler/README.chromium
@@ -3,7 +3,7 @@ URL: http://github.com/google/closure-compiler Version: v20150729-236-gad656a1 Date: 2015/08/26 08:46 -Revision: e061fc7bd4ac37730534828a9484d528fcd80eb5 +Revision: a13d0ba6d2b02b2188137b36cb699415bd8784c5 License: Apache 2.0 License File: LICENSE Security Critical: no
diff --git a/third_party/closure_compiler/compiler/compiler.jar b/third_party/closure_compiler/compiler/compiler.jar index b0ed94a7..80be348 100644 --- a/third_party/closure_compiler/compiler/compiler.jar +++ b/third_party/closure_compiler/compiler/compiler.jar Binary files differ
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 6a32012..a14da973 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -27,7 +27,7 @@ # Do NOT CHANGE this if you don't know what you're doing -- see # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md # Reverting problematic clang rolls is safe, though. -CLANG_REVISION = '305281' +CLANG_REVISION = '305462' use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ if use_head_revision:
diff --git a/tools/determinism/deterministic_build_whitelist.pyl b/tools/determinism/deterministic_build_whitelist.pyl index 5721b9d..c9c4472 100644 --- a/tools/determinism/deterministic_build_whitelist.pyl +++ b/tools/determinism/deterministic_build_whitelist.pyl
@@ -119,7 +119,6 @@ 'message_center_unittests', 'midi_unittests', 'mojo_common_unittests', - 'mojo_js_integration_tests', 'mojo_js_unittests', 'mojo_public_bindings_unittests', 'mojo_public_system_unittests', @@ -276,7 +275,6 @@ 'midi_unittests.exe', 'mini_installer.exe', 'mksnapshot.exe', - 'mojo_js_integration_tests.exe', 'mojo_js_unittests.exe', 'mojo_message_pipe_perftests.exe', 'mojo_public_bindings_perftests.exe',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index fb92ba6..25318ac 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -22,12 +22,12 @@ <enums> -<enum name="Abandoned" type="int"> +<enum name="Abandoned"> <int value="0" label="Finished"/> <int value="1" label="Abandoned"/> </enum> -<enum name="AbandonType" type="int"> +<enum name="AbandonType"> <int value="0" label="Not abandoned"/> <int value="1" label="FinishDoc missing"/> <int value="2" label="FinishAllLoads missing"/> @@ -47,13 +47,13 @@ label="LoadEventEnd+LoadEventStart+FinishAllLoads+FinishDoc missing"/> </enum> -<enum name="AcceleratedFixedRootBackground" type="int"> +<enum name="AcceleratedFixedRootBackground"> <int value="0" label="ScrolledMainFrame"/> <int value="1" label="ScrolledMainFrameWithAcceleratedFixedRootBackground"/> <int value="2" label="ScrolledMainFrameWithUnacceleratedFixedRootBackground"/> </enum> -<enum name="AccessibilityAndroidServiceInfoEnum" type="int"> +<enum name="AccessibilityAndroidServiceInfoEnum"> <summary> Track flags and capabilities of enabled accessibility services on Android. </summary> @@ -103,7 +103,7 @@ <int value="43" label="FLAG_RETRIEVE_INTERACTIVE_WINDOWS"/> </enum> -<enum name="AccessibilityModeFlagEnum" type="int"> +<enum name="AccessibilityModeFlagEnum"> <summary>Track individual accessibility mode flags that are enabled.</summary> <int value="0" label="Native APIs"/> <int value="1" label="Web Contents"/> @@ -112,7 +112,7 @@ <int value="4" label="HTML"/> </enum> -<enum name="AccessibilityWinAPIEnum" type="int"> +<enum name="AccessibilityWinAPIEnum"> <summary> Track which Windows accessibility APIs are being called by clients. </summary> @@ -346,20 +346,20 @@ <int value="157" label="UMA_API_UNSELECT_ROW">unselectRow</int> </enum> -<enum name="AccountChooserDismissalReason" type="int"> +<enum name="AccountChooserDismissalReason"> <int value="0" label="Canceled"/> <int value="1" label="Credential chosen"/> <int value="2" label="Sign in clicked"/> </enum> -<enum name="AccountChooserUsabilityState" type="int"> +<enum name="AccountChooserUsabilityState"> <int value="0" label="Looks OK"/> <int value="1" label="Empty username"/> <int value="2" label="Duplicate usernames"/> <int value="3" label="Empty and duplicate usernames"/> </enum> -<enum name="AccountRelation" type="int"> +<enum name="AccountRelation"> <int value="0" label="Empty cookie jar"/> <int value="1" label="No signed in, single signed out match"/> <int value="2" label="No signed in, one of multiple signed out match"/> @@ -371,19 +371,19 @@ <int value="8" label="With signed in, no match"/> </enum> -<enum name="ActionAfterDoubleTap" type="int"> +<enum name="ActionAfterDoubleTap"> <int value="0" label="Navigated Back"/> <int value="1" label="Stopped Navigation"/> <int value="2" label="No Action"/> </enum> -<enum name="ActionUponResourceRequest" type="int"> +<enum name="ActionUponResourceRequest"> <int value="0" label="Load resource"/> <int value="1" label="Revalidate resource"/> <int value="2" label="Use resource from cache"/> </enum> -<enum name="ActiveWindowShowType" type="int"> +<enum name="ActiveWindowShowType"> <int value="0" label="No Active Window"/> <int value="1" label="Other"/> <int value="2" label="Maximized"/> @@ -394,7 +394,7 @@ <int value="7" label="TrustedPinned"/> </enum> -<enum name="ActivityTrackerAnalyzerCreationError" type="int"> +<enum name="ActivityTrackerAnalyzerCreationError"> <int value="0" label="Invalid memory mapped file"/> <int value="1" label="PMA bad file"/> <int value="2" label="PMA uninitialized"/> @@ -402,14 +402,14 @@ <int value="4" label="PMA corrupt"/> </enum> -<enum name="ActivityTrackerCollectInitStatus" type="int"> +<enum name="ActivityTrackerCollectInitStatus"> <int value="0" label="Success"/> <int value="1" label="Unknown directory"/> <int value="2" label="Get stability file path failed"/> <int value="3" label="Crashpad database init failed"/> </enum> -<enum name="ActivityTrackerCollectOnCrashEvent" type="int"> +<enum name="ActivityTrackerCollectOnCrashEvent"> <int value="0" label="Collection attempt"/> <int value="1" label="User data directory not empty"/> <int value="2" label="Path exists"/> @@ -419,7 +419,7 @@ <int value="6" label="Success"/> </enum> -<enum name="ActivityTrackerCollectStatus" type="int"> +<enum name="ActivityTrackerCollectStatus"> <int value="0" label="None"/> <int value="1" label="Sucess"/> <int value="2" label="Analyzer creation failed"/> @@ -433,7 +433,7 @@ <int value="10" label="Collection attempt"/> </enum> -<enum name="ActivityTrackerRecordEvent" type="int"> +<enum name="ActivityTrackerRecordEvent"> <int value="0" label="Recording attempt"/> <int value="1" label="Stability directory exists"/> <int value="2" label="Got stability file path"/> @@ -443,7 +443,7 @@ <int value="6" label="Open for delete failed"/> </enum> -<enum name="ActivityTrackerRecordInitStatus" type="int"> +<enum name="ActivityTrackerRecordInitStatus"> <obsolete> Removed from code May 2017. </obsolete> @@ -452,7 +452,7 @@ <int value="2" label="Get stability file path failed"/> </enum> -<enum name="ActivityTrackerSystemSessionAnalysisStatus" type="int"> +<enum name="ActivityTrackerSystemSessionAnalysisStatus"> <int value="0" label="Success"/> <int value="1" label="Missing timestamp"/> <int value="2" label="Missing analyzer"/> @@ -460,19 +460,19 @@ <int value="4" label="Outside range"/> </enum> -<enum name="ActivityTrackerWriteDumpStatus" type="int"> +<enum name="ActivityTrackerWriteDumpStatus"> <int value="0" label="Sucess"/> <int value="1" label="Failed"/> <int value="2" label="Failed (missing product details)"/> </enum> -<enum name="AddressFamily" type="int"> +<enum name="AddressFamily"> <int value="0" label="Unspecified"/> <int value="1" label="IPv4"/> <int value="2" label="IPv6"/> </enum> -<enum name="AddSearchProvider" type="int"> +<enum name="AddSearchProvider"> <int value="0" label="window.external.AddSearchProvider was called"/> <int value="1" label="A confirmation dialog was shown"/> <int value="2" label="The user added a search engine via the dialog"/> @@ -480,13 +480,13 @@ label="The user saw the dialog but closed it without adding an engine"/> </enum> -<enum name="AffiliationFetchResult" type="int"> +<enum name="AffiliationFetchResult"> <int value="0" label="Success"/> <int value="1" label="Network/server error"/> <int value="2" label="Malformed response"/> </enum> -<enum name="AlternateProtocolUsage" type="int"> +<enum name="AlternateProtocolUsage"> <int value="0" label="ALTERNATE_PROTOCOL_USAGE_NO_RACE"/> <int value="1" label="ALTERNATE_PROTOCOL_USAGE_WON_RACE"/> <int value="2" label="ALTERNATE_PROTOCOL_USAGE_LOST_RACE"/> @@ -494,7 +494,7 @@ <int value="4" label="ALTERNATE_PROTOCOL_USAGE_BROKEN"/> </enum> -<enum name="AlternativeServiceType" type="int"> +<enum name="AlternativeServiceType"> <int value="0" label="No alternative service"/> <int value="1" label="QUIC, destination same as origin"/> <int value="2" label="QUIC, destination different from origin"/> @@ -502,7 +502,7 @@ <int value="4" label="Not QUIC, destination different from origin"/> </enum> -<enum name="AndroidActivityId" type="int"> +<enum name="AndroidActivityId"> <int value="1" label="Unknown"/> <int value="2" label="Main"/> <int value="3" label="Preferences"/> @@ -510,7 +510,7 @@ <int value="5" label="FullScreenActivity"/> </enum> -<enum name="AndroidActivityStopReason" type="int"> +<enum name="AndroidActivityStopReason"> <int value="0" label="Unknown"/> <int value="1" label="Chrome sent to background by system back"> The user pressed the system back button, sending Chrome to the background. @@ -532,7 +532,7 @@ </int> </enum> -<enum name="AndroidActivitySystemBackAction" type="int"> +<enum name="AndroidActivitySystemBackAction"> <int value="0" label="Nothing happened"/> <int value="1" label="The foreground tab contained a help article and was closed"/> @@ -548,12 +548,12 @@ <int value="8" label="User navigated backward in the tab's history"/> </enum> -<enum name="AndroidArmFpu" type="int"> +<enum name="AndroidArmFpu"> <int value="0" label="No NEON support"/> <int value="1" label="NEON support"/> </enum> -<enum name="AndroidDownloadExtensionType" type="int"> +<enum name="AndroidDownloadExtensionType"> <int value="0" label="Other"/> <int value="1" label="APK"/> <int value="2" label="CSV"/> @@ -571,7 +571,7 @@ <int value="14" label="ZIP"/> </enum> -<enum name="AndroidDownloadFilterType" type="int"> +<enum name="AndroidDownloadFilterType"> <int value="0" label="All"/> <int value="1" label="Page"/> <int value="2" label="Video"/> @@ -581,7 +581,7 @@ <int value="6" label="Other"/> </enum> -<enum name="AndroidEvictionReason" type="int"> +<enum name="AndroidEvictionReason"> <int value="0" label="TabUnusedTooLong"/> <int value="1" label="TabUnusedInSession"/> <int value="2" label="LimitOfActiveTabs"/> @@ -589,7 +589,7 @@ <int value="4" label="EvictAll"/> </enum> -<enum name="AndroidFeedbackCategory" type="int"> +<enum name="AndroidFeedbackCategory"> <summary> This list corresponds to the categories the user can press when selecting a category their feedback falls under. @@ -600,7 +600,7 @@ <int value="3" label="Trouble with something else"/> </enum> -<enum name="AndroidFeedbackCategoryDetails" type="int"> +<enum name="AndroidFeedbackCategoryDetails"> <summary> This list corresponds to all the possible options a user can press when selecting an option their feedback falls under. Each option is prefixed with @@ -628,7 +628,7 @@ <int value="19" label="Something Other"/> </enum> -<enum name="AndroidGATTConnectionErrorCodes" type="int"> +<enum name="AndroidGATTConnectionErrorCodes"> <summary> This list includes all errors from the Bluetooth Specification Version 4.2 [Vol 2, Part D] as well as an error from Android's BluetoothGatt (0x101 @@ -715,7 +715,7 @@ <int value="257" label="0x101 Android GATT Failure"/> </enum> -<enum name="AndroidGATTStatusResult" type="int"> +<enum name="AndroidGATTStatusResult"> <summary> This list includes errors from the Bluetooth Specification Version 4.2 Vol 3, Part F, Section 3.4.1.1 and Core Specification Supplement Part B. Also @@ -781,7 +781,7 @@ <int value="257" label="GATT_FAILURE"/> </enum> -<enum name="AndroidKernelVersion" type="int"> +<enum name="AndroidKernelVersion"> <int value="131078" label="2.6"/> <int value="196608" label="3.0"/> <int value="196609" label="3.1"/> @@ -805,27 +805,27 @@ <int value="262154" label="4.10"/> </enum> -<enum name="AndroidManageSpaceButton" type="int"> +<enum name="AndroidManageSpaceButton"> <int value="0" label="Clear Unimportant Storage"/> <int value="1" label="Manage Site Storage"/> <int value="2" label="Clear App Data"/> </enum> -<enum name="AndroidMemoryNotificationBackground" type="int"> +<enum name="AndroidMemoryNotificationBackground"> <int value="0" label="TrimMemoryUiHidden"/> <int value="1" label="TrimMemoryBackground"/> <int value="2" label="TrimMemoryModerate"/> <int value="3" label="TrimMemoryComplete"/> </enum> -<enum name="AndroidMemoryNotificationForeground" type="int"> +<enum name="AndroidMemoryNotificationForeground"> <int value="0" label="TrimMemoryRunningModerate"/> <int value="1" label="TrimMemoryRunningLow"/> <int value="2" label="TrimMemoryRunningCritical"/> <int value="3" label="LowMemory"/> </enum> -<enum name="AndroidRestoreResult" type="int"> +<enum name="AndroidRestoreResult"> <int value="0" label="No restore attempted"/> <int value="1" label="Restore successful"/> <int value="2" label="Failed: Chrome already run locally"/> @@ -833,7 +833,7 @@ <int value="4" label="Failed: Cannot sign in as previous user"/> </enum> -<enum name="AndroidSeccompSandboxStatus" type="int"> +<enum name="AndroidSeccompSandboxStatus"> <int value="0" label="Not Supported"/> <int value="1" label="Detection Failed"/> <int value="2" label="Feature Disabled"/> @@ -841,13 +841,13 @@ <int value="4" label="Sandbox Engaged"/> </enum> -<enum name="AndroidSeccompStatus" type="int"> +<enum name="AndroidSeccompStatus"> <int value="0" label="Detection Failed"/> <int value="1" label="Not Supported"/> <int value="2" label="Supported"/> </enum> -<enum name="AndroidSigninPromoAction" type="int"> +<enum name="AndroidSigninPromoAction"> <int value="0" label="Promo enabled"> The Android signin promo was enabled to show on next startup. </int> @@ -864,7 +864,7 @@ </int> </enum> -<enum name="AndroidTabCloseUndoToastEvent" type="int"> +<enum name="AndroidTabCloseUndoToastEvent"> <int value="0" label="Undo Shown (Cold)"/> <int value="1" label="Undo Shown (Warm)"/> <int value="2" label="Undo Pressed"/> @@ -872,7 +872,7 @@ <int value="4" label="Undos Dismissed (Action) (Deprecated)"/> </enum> -<enum name="AntiVirusMetricsProviderResult" type="int"> +<enum name="AntiVirusMetricsProviderResult"> <int value="0" label="RESULT_SUCCESS"/> <int value="1" label="RESULT_GENERIC_FAILURE"/> <int value="2" label="RESULT_FAILED_TO_INITIALIZE_COM"/> @@ -891,7 +891,7 @@ <int value="15" label="RESULT_WSC_NOT_AVAILABLE"/> </enum> -<enum name="AppBannersBeforeInstallEvent" type="int"> +<enum name="AppBannersBeforeInstallEvent"> <int value="1" label="Event created and dispatched"/> <int value="2" label="Showing the banner"/> <int value="3" label="preventDefault() not called"/> @@ -900,7 +900,7 @@ <int value="6" label="prompt() not called after preventDefault()"/> </enum> -<enum name="AppBannersDismissEvent" type="int"> +<enum name="AppBannersDismissEvent"> <int value="41" label="Error/unknown reason for dismissal"/> <int value="42" label="User opened the application after installing it"/> <int value="43" label="User clicked on the banner"/> @@ -910,7 +910,7 @@ <int value="47" label="Banner was dismissed for any reason"/> </enum> -<enum name="AppBannersDisplayEvent" type="int"> +<enum name="AppBannersDisplayEvent"> <int value="1" label="Banner was requested by the site"/> <int value="2" label="User previously blocked the same banner"/> <int value="3" label="User blocked too many other banners from the site"/> @@ -925,7 +925,7 @@ <int value="12" label="Web app banner created"/> </enum> -<enum name="AppBannersInstallableStatusCode" type="int"> +<enum name="AppBannersInstallableStatusCode"> <int value="0" label="No error"/> <int value="1" label="Renderer exiting"/> <int value="2" label="Renderer called beforeinstallprompt.preventDefault()"/> @@ -958,7 +958,7 @@ <int value="29" label="Service worker not offline capable"/> </enum> -<enum name="AppBannersInstallEvent" type="int"> +<enum name="AppBannersInstallEvent"> <int value="21" label="(Native app) User triggered the app install dialog"/> <int value="22" label="(Native app) User began installing the app"/> <int value="23" @@ -966,7 +966,7 @@ <int value="24" label="(Web app) User installed a web app"/> </enum> -<enum name="AppBannersUserResponse" type="int"> +<enum name="AppBannersUserResponse"> <int value="1" label="Native app banner was accepted by the user"/> <int value="2" label="Web app banner was accepted by the user"/> <int value="3" label="Native app banner was dismissed by the user"/> @@ -975,7 +975,7 @@ <int value="6" label="Web app banner was ignored by the user"/> </enum> -<enum name="AppCacheCheckResponseResult" type="int"> +<enum name="AppCacheCheckResponseResult"> <int value="0" label="OK"/> <int value="1" label="Manifest obsolete"/> <int value="2" label="Response obsolete"/> @@ -986,17 +986,17 @@ <int value="7" label="Check canceled"/> </enum> -<enum name="AppCacheErrorSite" type="int"> +<enum name="AppCacheErrorSite"> <summary>Identifies the point of failure, see sources.</summary> </enum> -<enum name="AppCacheInitResult" type="int"> +<enum name="AppCacheInitResult"> <int value="0" label="OK"/> <int value="1" label="SQL Database Error"/> <int value="2" label="Disk Cache Error"/> </enum> -<enum name="AppCacheUpdateJobResult" type="int"> +<enum name="AppCacheUpdateJobResult"> <int value="0" label="OK"/> <int value="1" label="SQL Database Error"/> <int value="2" label="Disk Cache Error"/> @@ -1009,13 +1009,13 @@ <int value="9" label="Security Error"/> </enum> -<enum name="AppInfoDialogLaunchOrigin" type="int"> +<enum name="AppInfoDialogLaunchOrigin"> <int value="0" label="App List context menu"/> <int value="1" label="Extensions page"/> <int value="2" label="Apps Page context menu"/> </enum> -<enum name="AppLaunch" type="int"> +<enum name="AppLaunch"> <int value="0" label="NTP_APPS_MAXIMIZED"/> <int value="1" label="NTP_APPS_COLLAPSED"/> <int value="2" label="NTP_APPS_MENU"/> @@ -1044,21 +1044,21 @@ <int value="25" label="APP_LIST_SEARCH_WEBSTORE"/> </enum> -<enum name="AppLaunchContainer" type="int"> +<enum name="AppLaunchContainer"> <int value="0" label="LAUNCH_CONTAINER_WINDOW"/> <int value="1" label="LAUNCH_CONTAINER_PANEL"/> <int value="2" label="LAUNCH_CONTAINER_TAB"/> <int value="3" label="LAUNCH_CONTAINER_NONE (v2 packaged apps)"/> </enum> -<enum name="AppLauncherPromo" type="int"> +<enum name="AppLauncherPromo"> <int value="0" label="Already installed"/> <int value="1" label="Shown"/> <int value="2" label="Dismissed"/> <int value="3" label="Learn more"/> </enum> -<enum name="AppLaunchSource" type="int"> +<enum name="AppLaunchSource"> <int value="0" label="LAUNCH_SOURCE_NONE"/> <int value="1" label="LAUNCH_SOURCE_UNTRACKED"/> <int value="2" label="LAUNCH_SOURCE_APP_LAUNCHER"/> @@ -1082,7 +1082,7 @@ <int value="20" label="LAUNCH_SOURCE_INSTALLED_NOTIFICATION"/> </enum> -<enum name="AppleScriptCommandEvents" type="int"> +<enum name="AppleScriptCommandEvents"> <int value="0" label="Tab Close"/> <int value="1" label="Tab Copy"/> <int value="2" label="Tab Cut"/> @@ -1103,12 +1103,12 @@ <int value="17" label="Window Exit Presentation Mode"/> </enum> -<enum name="AppListDoodleAction" type="int"> +<enum name="AppListDoodleAction"> <int value="0" label="DOODLE_SHOWN"/> <int value="1" label="DOODLE_CLICKED"/> </enum> -<enum name="AppListEnableSource" type="int"> +<enum name="AppListEnableSource"> <int value="0" label="Not enabled (should never be recorded)"/> <int value="1" label="Packaged app installed from Web Store"/> <int value="2" label="Clicked app launcher link from the Web Store"/> @@ -1117,14 +1117,14 @@ <int value="5" label="Second packaged app installed without showing"/> </enum> -<enum name="AppListPage" type="int"> +<enum name="AppListPage"> <int value="0" label="APPS"/> <int value="1" label="SEARCH_RESULTS"/> <int value="2" label="START"/> <int value="3" label="CUSTOM_LAUNCHER_PAGE"/> </enum> -<enum name="AppListSearchResult" type="int"> +<enum name="AppListSearchResult"> <int value="0" label="OMNIBOX"/> <int value="1" label="APP"/> <int value="2" label="WEBSTORE"/> @@ -1134,21 +1134,21 @@ <int value="6" label="LAUNCHER_SEARCH_PROVIDER"/> </enum> -<enum name="AppListSearchResultDisplayType" type="int"> +<enum name="AppListSearchResultDisplayType"> <int value="0" label="NONE"/> <int value="1" label="LIST"/> <int value="2" label="TILE"/> <int value="3" label="RECOMMENDATION"/> </enum> -<enum name="AppLoadedInTabSource" type="int"> +<enum name="AppLoadedInTabSource"> <int value="0" label="SOURCE_APP"/> <int value="1" label="SOURCE_BACKGROUND_PAGE"/> <int value="2" label="SOURCE_OTHER_EXTENSION"/> <int value="3" label="SOURCE_OTHER"/> </enum> -<enum name="AppLocation" type="int"> +<enum name="AppLocation"> <int value="0" label="Invalid location"/> <int value="1" label="Internal extension"/> <int value="2" label="Internal extension (loaded via prefs)"/> @@ -1162,7 +1162,7 @@ <int value="10" label="Component app (downloaded)"/> </enum> -<enum name="AppPromoAction" type="int"> +<enum name="AppPromoAction"> <int value="0" label="PROMO_LAUNCH_APP"/> <int value="1" label="PROMO_LAUNCH_WEB_STORE"/> <int value="2" label="PROMO_CLOSE"/> @@ -1170,7 +1170,7 @@ <int value="4" label="PROMO_SEEN"/> </enum> -<enum name="AppsPageDragSource" type="int"> +<enum name="AppsPageDragSource"> <int value="0" label="Same apps pane"/> <int value="1" label="Different apps pane"/> <int value="2" label="Most visited pane"/> @@ -1178,7 +1178,7 @@ <int value="4" label="Outside of NTP (e.g. bookmarks bar)"/> </enum> -<enum name="ArcAuthAccountCheckStatus" type="int"> +<enum name="ArcAuthAccountCheckStatus"> <int value="0" label="Account is up to date"/> <int value="1" label="New account"/> <int value="2" label="Account needs reauth"/> @@ -1186,7 +1186,7 @@ <int value="4" label="Account check failed"/> </enum> -<enum name="ArcIntentHandlerAction" type="int"> +<enum name="ArcIntentHandlerAction"> <summary>Defines Arc intent handler actions</summary> <int value="0" label="Error"/> <int value="1" label="Dialog deactivated"/> @@ -1195,7 +1195,7 @@ <int value="4" label="Preferred activity found"/> </enum> -<enum name="ArcIntentHandlerDestinationPlatform" type="int"> +<enum name="ArcIntentHandlerDestinationPlatform"> <summary> Defines ARC intent handler platforms to continue the navigation. </summary> @@ -1203,7 +1203,7 @@ <int value="1" label="Chrome"/> </enum> -<enum name="ArcOptInAction" type="int"> +<enum name="ArcOptInAction"> <summary>Defines Arc OptIn actions</summary> <int value="0" label="Opted Out"/> <int value="1" label="Opted In"/> @@ -1213,7 +1213,7 @@ <int value="5" label="Retry after OptIn failure"/> </enum> -<enum name="ArcOptInCancel" type="int"> +<enum name="ArcOptInCancel"> <summary>Defines Arc OptIn cancel reason</summary> <int value="0" label="Canceled by user"/> <int value="1" label="Unclassified failure"/> @@ -1226,7 +1226,7 @@ <int value="8" label="Busy"/> </enum> -<enum name="ArcOptInResult" type="int"> +<enum name="ArcOptInResult"> <summary> Defines Arc OptIn flow states. Normally each OptIn flow reports 2-3 states; Started should be accompined with Succeeded or Canceled. Optionally @@ -1239,7 +1239,7 @@ <int value="4" label="Canceled after error"/> </enum> -<enum name="ArcOptInSilentAuthCode" type="int"> +<enum name="ArcOptInSilentAuthCode"> <summary>Defines Arc OptIn Silent Auth code state</summary> <int value="0" label="Disabled"/> <int value="1" label="Success"/> @@ -1252,7 +1252,7 @@ <int value="8" label="No Auth code in response"/> </enum> -<enum name="ArcProvisioningResult" type="int"> +<enum name="ArcProvisioningResult"> <summary>Defines Arc Provisioning success and failure reasons</summary> <int value="0" label="Success"/> <int value="1" label="Unclassified failure"/> @@ -1275,7 +1275,7 @@ <int value="19" label="Network is unavailable"/> </enum> -<enum name="ArcVideoDecodeAcceleratorResult" type="int"> +<enum name="ArcVideoDecodeAcceleratorResult"> <summary>Defines ArcVideoDecodeAccelerator initialization status</summary> <int value="0" label="SUCCESS"/> <int value="1" label="ILLEGAL_STATE"/> @@ -1285,7 +1285,7 @@ <int value="5" label="INSUFFICIENT_RESOURCES"/> </enum> -<enum name="AsyncDNSConfigParsePosix" type="int"> +<enum name="AsyncDNSConfigParsePosix"> <int value="0" label="OK"/> <int value="1" label="RES_INIT_FAILED"/> <int value="2" label="RES_INIT_UNSET"/> @@ -1297,7 +1297,7 @@ <int value="8" label="UNHANDLED_OPTIONS"/> </enum> -<enum name="AsyncDNSConfigParseWin" type="int"> +<enum name="AsyncDNSConfigParseWin"> <int value="0" label="OK"/> <int value="1" label="READ_IPHELPER"/> <int value="2" label="READ_POLICY_SEARCHLIST"/> @@ -1313,7 +1313,7 @@ <int value="12" label="UNHANDLED_OPTIONS"/> </enum> -<enum name="AsyncDNSHostsParseWin" type="int"> +<enum name="AsyncDNSHostsParseWin"> <int value="0" label="OK"/> <int value="1" label="UNREADABLE_HOSTS_FILE"/> <int value="2" label="COMPUTER_NAME_FAILED"/> @@ -1321,7 +1321,7 @@ <int value="4" label="BAD_ADDRESS"/> </enum> -<enum name="AsyncDNSNameServersType" type="int"> +<enum name="AsyncDNSNameServersType"> <summary>Type of nameservers in the DNS config.</summary> <int value="0" label="NONE">No nameservers configured.</int> <int value="1" label="GOOGLE_PUBLIC_DNS"> @@ -1340,7 +1340,7 @@ </int> </enum> -<enum name="AsyncDNSParseResult" type="int"> +<enum name="AsyncDNSParseResult"> <summary>Results of DnsResponse::ParseToAddressList.</summary> <int value="0" label="SUCCESS"/> <int value="1" label="MALFORMED_RESPONSE"/> @@ -1352,13 +1352,13 @@ <int value="7" label="NO_ADDRESSES"/> </enum> -<enum name="AsyncDNSPrefDefaultSource" type="int"> +<enum name="AsyncDNSPrefDefaultSource"> <int value="0" label="PLATFORM"/> <int value="1" label="FIELD_TRIAL"/> <int value="2" label="HARD_CODED_DEFAULT"/> </enum> -<enum name="AsyncDNSPrefSource" type="int"> +<enum name="AsyncDNSPrefSource"> <int value="0" label="MANAGED_PREF"/> <int value="1" label="SUPERVISED_PREF"/> <int value="2" label="EXTENSION_PREF"/> @@ -1369,7 +1369,7 @@ <int value="7" label="UNKNOWN_PREF"/> </enum> -<enum name="AsyncDNSResolveStatus" type="int"> +<enum name="AsyncDNSResolveStatus"> <int value="0" label="DNS_SUCCESS">Succeeded with async DNS.</int> <int value="1" label="PROC_SUCCESS"> Succeeded with getaddrinfo after async DNS failed. @@ -1380,7 +1380,7 @@ </int> </enum> -<enum name="AsyncDNSWatchStatus" type="int"> +<enum name="AsyncDNSWatchStatus"> <int value="0" label="STARTED">Started.</int> <int value="1" label="FAILED_TO_START_CONFIG"> Failed to start watching config. @@ -1392,7 +1392,7 @@ <int value="4" label="FAILED_HOSTS">Failed during watching HOSTS.</int> </enum> -<enum name="AsyncRevalidationResult" type="int"> +<enum name="AsyncRevalidationResult"> <int value="0" label="LOADED">A new entry was stored in the cache.</int> <int value="1" label="REVALIDATED"> The existing cache entry was revalidated. @@ -1416,7 +1416,7 @@ </int> </enum> -<enum name="AttachmentServicesResult" type="int"> +<enum name="AttachmentServicesResult"> <int value="0" label="Succeeded with MOTW"/> <int value="1" label="Succeeded without MOTW"/> <int value="2" label="Succeeded but file was missing"/> @@ -1432,7 +1432,7 @@ <int value="12" label="Other error (file missing)"/> </enum> -<enum name="AudioCaptureStartupResult" type="int"> +<enum name="AudioCaptureStartupResult"> <int value="0" label="OK"/> <int value="1" label="Failed to create stream"/> <int value="2" label="Failed to open stream"/> @@ -1440,7 +1440,7 @@ <int value="4" label="No data received and capture stopped within 500ms"/> </enum> -<enum name="AudioCodec" type="int"> +<enum name="AudioCodec"> <int value="0" label="kUnknownAudioCodec"/> <int value="1" label="kCodecAAC"/> <int value="2" label="kCodecMP3"/> @@ -1460,7 +1460,7 @@ <int value="16" label="kCodecAC3"/> </enum> -<enum name="AudioDevicePropertyResult" type="int"> +<enum name="AudioDevicePropertyResult"> <int value="0" label="Other"/> <int value="1" label="Device has changed"/> <int value="2" label="IO stopped abnormally"/> @@ -1518,7 +1518,7 @@ <int value="54" label="Sub mute"/> </enum> -<enum name="AudioFramesPerBuffer" type="int"> +<enum name="AudioFramesPerBuffer"> <obsolete> Removed from code Sep 2014. </obsolete> @@ -1533,24 +1533,24 @@ <int value="8" label="k1920"/> </enum> -<enum name="AudioGlitchResult" type="int"> +<enum name="AudioGlitchResult"> <int value="0" label="No audio glitches"/> <int value="1" label="Audio glitches"/> </enum> -<enum name="AudioInputSilenceReport" type="int"> +<enum name="AudioInputSilenceReport"> <int value="0" label="No measurement"/> <int value="1" label="Only audio"/> <int value="2" label="Only silence"/> <int value="3" label="Audio and silence"/> </enum> -<enum name="AudioRendererEvents" type="int"> +<enum name="AudioRendererEvents"> <int value="0" label="Initialized"/> <int value="1" label="Runtime error"/> </enum> -<enum name="AudioSampleFormat" type="int"> +<enum name="AudioSampleFormat"> <int value="0" label="Unknown"/> <int value="1" label="Unsigned 8-bit"/> <int value="2" label="Signed 16-bit"/> @@ -1560,7 +1560,7 @@ <int value="6" label="Float 32-bit planar"/> </enum> -<enum name="AudioSampleRate" type="int"> +<enum name="AudioSampleRate"> <int value="0" label="8 kHz"/> <int value="1" label="16 kHz"/> <int value="2" label="32 kHz"/> @@ -1576,7 +1576,7 @@ <int value="12" label="384 kHz"/> </enum> -<enum name="AudioStreamOpenResult" type="int"> +<enum name="AudioStreamOpenResult"> <int value="0" label="OK"/> <int value="1" label="CREATE_INSTANCE"/> <int value="2" label="NO_ENDPOINT"/> @@ -1594,20 +1594,20 @@ <int value="14" label="OK_WITH_RESAMPLING"/> </enum> -<enum name="AudioThreadStatus" type="int"> +<enum name="AudioThreadStatus"> <int value="0" label="None"/> <int value="1" label="Started"/> <int value="2" label="Hung"/> <int value="3" label="Recovered"/> </enum> -<enum name="AudioTrackProcessingStates" type="int"> +<enum name="AudioTrackProcessingStates"> <int value="0" label="Enabled"/> <int value="1" label="Disabled"/> <int value="2" label="Processing in WebRTC"/> </enum> -<enum name="AuthPolicyErrorType" type="int"> +<enum name="AuthPolicyErrorType"> <int value="0" label="Success"/> <int value="1" label="Unspecified error"/> <int value="2" label="Unspecified D-Bus error"/> @@ -1640,7 +1640,7 @@ <int value="27" label="kinit failed because of bad machine name."/> </enum> -<enum name="AutocheckoutBubble" type="int"> +<enum name="AutocheckoutBubble"> <obsolete> Deprecated as of 8/2013. </obsolete> @@ -1651,7 +1651,7 @@ <int value="4" label="Could be displayed"/> </enum> -<enum name="AutocheckoutBuyFlow" type="int"> +<enum name="AutocheckoutBuyFlow"> <obsolete> Deprecated as of 8/2013. </obsolete> @@ -1662,7 +1662,7 @@ <int value="4" label="Cannot proceed"/> </enum> -<enum name="AutofillCardUploadDecision" type="int"> +<enum name="AutofillCardUploadDecision"> <obsolete> Deprecated as of 2/2016, replaced by AutofillCardUploadDecisionExpanded. </obsolete> @@ -1672,7 +1672,7 @@ <int value="3" label="Upload not offered, get upload details RPC failed"/> </enum> -<enum name="AutofillCardUploadDecisionExpanded" type="int"> +<enum name="AutofillCardUploadDecisionExpanded"> <obsolete> Deprecated as of 5/2017, replaced by AutofillCardUploadDecisionMetric. </obsolete> @@ -1689,7 +1689,7 @@ <int value="8" label="Upload offered, no CVC detected"/> </enum> -<enum name="AutofillCardUploadDecisionMetric" type="int"> +<enum name="AutofillCardUploadDecisionMetric"> <int value="0" label="Upload offered"/> <int value="1" label="CVC field not detected"/> <int value="2" label="CVC value not filled in detected CVC field"/> @@ -1708,20 +1708,20 @@ <int value="11" label="Get upload details RPC failed"/> </enum> -<enum name="AutofillCreditCardInfoBar" type="int"> +<enum name="AutofillCreditCardInfoBar"> <int value="0" label="Shown"/> <int value="1" label="Accepted"/> <int value="2" label="Denied"/> <int value="3" label="Ignored"/> </enum> -<enum name="AutofillDeveloperEngagement" type="int"> +<enum name="AutofillDeveloperEngagement"> <int value="0" label="Fillable form parsed without type hints"/> <int value="1" label="Fillable form parsed with type hints"/> <int value="2" label="Includes UPI-VPA type hint"/> </enum> -<enum name="AutofillDialogDismissalState" type="int"> +<enum name="AutofillDialogDismissalState"> <int value="0" label="Submitted, existing data (deprecated)"/> <int value="1" label="Submitted, saved to Wallet"/> <int value="2" label="Submitted, saved locally"/> @@ -1734,7 +1734,7 @@ <int value="9" label="Submitted, existing data came from Autofill"/> </enum> -<enum name="AutofillDialogInitialUserState" type="int"> +<enum name="AutofillDialogInitialUserState"> <int value="0" label="Not signed in, no Autofill"/> <int value="1" label="Not signed in, has Autofill"/> <int value="2" label="Signed in, no Wallet, no Autofill"/> @@ -1743,18 +1743,18 @@ <int value="5" label="Signed in, ha Wallet, has Autofill"/> </enum> -<enum name="AutofillDialogPopupEvent" type="int"> +<enum name="AutofillDialogPopupEvent"> <int value="0" label="Popup shown"/> <int value="1" label="Form Autofilled"/> </enum> -<enum name="AutofillDialogSecurity" type="int"> +<enum name="AutofillDialogSecurity"> <int value="0" label="Baseline: Dialog shown"/> <int value="1" label="Credit card over HTTP"/> <int value="2" label="Cross-origin frame"/> </enum> -<enum name="AutofillDialogUiEvents" type="int"> +<enum name="AutofillDialogUiEvents"> <int value="0" label="Dialog shown"/> <int value="1" label="Dialog submitted"/> <int value="2" label="Dialog canceled"/> @@ -1781,7 +1781,7 @@ <int value="22" label="Account switched: Wallet account added (multilogin)"/> </enum> -<enum name="AutofillExperimentId" type="int"> +<enum name="AutofillExperimentId"> <int value="0" label="No Experiment"/> <int value="1" label="Unknown"/> <int value="2" label="ar06"/> @@ -1802,7 +1802,7 @@ <int value="17" label="fp05cc03e1"/> </enum> -<enum name="AutofillFieldPredictionQuality" type="int"> +<enum name="AutofillFieldPredictionQuality"> <int value="0" label="True Positive"/> <int value="1" label="True Negative (Ambiguous)"/> <int value="2" label="True Negative (Unknown)"/> @@ -1815,7 +1815,7 @@ <int value="9" label="False Negative (Unknown)"/> </enum> -<enum name="AutofillFieldPredictionQualityByFieldType" type="int"> +<enum name="AutofillFieldPredictionQualityByFieldType"> <int value="0" label="Ambiguous: True Positive"/> <int value="1" label="Ambiguous: True Negative (Ambiguous)"/> <int value="2" label="Ambiguous: True Negative (Unknown)"/> @@ -2028,7 +2028,7 @@ <int value="5129" label="CVC: False Negative (Unknown)"/> </enum> -<enum name="AutofillFormEvent" type="int"> +<enum name="AutofillFormEvent"> <int value="0" label="Interacted (once)"/> <int value="1" label="Suggestions shown"/> <int value="2" label="Suggestions shown (once)"/> @@ -2063,7 +2063,7 @@ <int value="20" label="About to be submitted with suggestion shown (once)"/> </enum> -<enum name="AutofillFormSubmittedState" type="int"> +<enum name="AutofillFormSubmittedState"> <int value="0" label="Non fillable form or new data"/> <int value="1" label="Fillable form, autofilled all"/> <int value="2" label="Fillable form, autofilled some"/> @@ -2072,14 +2072,14 @@ label="Fillable form, autofilled none, did not show suggestions"/> </enum> -<enum name="AutofillGetRealPanResult" type="int"> +<enum name="AutofillGetRealPanResult"> <int value="0" label="Success"/> <int value="1" label="Retriable failure"/> <int value="2" label="Non retriable failure"/> <int value="3" label="Network error"/> </enum> -<enum name="AutofillKeyboardAccessoryButtonsIOS" type="int"> +<enum name="AutofillKeyboardAccessoryButtonsIOS"> <int value="0" label="Forms loaded"/> <int value="1" label="Submitted form"/> <int value="2" label="Close button pressed"/> @@ -2090,18 +2090,18 @@ <int value="7" label="Previous button pressed (once)"/> </enum> -<enum name="AutofillMacAddressBook" type="int"> +<enum name="AutofillMacAddressBook"> <int value="0" label="Showed popup entry"/> <int value="1" label="Selected popup entry"/> </enum> -<enum name="AutofillProfileAction" type="int"> +<enum name="AutofillProfileAction"> <int value="0" label="Existing profile used"/> <int value="1" label="Existing profile updated"/> <int value="2" label="New profile created"/> </enum> -<enum name="AutofillQuality" type="int"> +<enum name="AutofillQuality"> <int value="0" label="Submitted"/> <int value="1" label="Autofilled"/> <int value="2" label="Autofill failed"/> @@ -2113,7 +2113,7 @@ <int value="8" label="Server Mismatch"/> </enum> -<enum name="AutofillQueryResult" type="int"> +<enum name="AutofillQueryResult"> <int value="0" label="Sent"/> <int value="1" label="Received"/> <int value="2" label="Parsed"/> @@ -2122,7 +2122,7 @@ <int value="5" label="Response improves local (empty)"/> </enum> -<enum name="AutofillSaveCreditCardPrompt" type="int"> +<enum name="AutofillSaveCreditCardPrompt"> <int value="0" label="Show requested"/> <int value="1" label="Shown"/> <int value="2" label="Ended, invalid legal message"/> @@ -2134,13 +2134,13 @@ <int value="8" label="Dismissed, user clicked a legal message link"/> </enum> -<enum name="AutofillScanCreditCardPrompt" type="int"> +<enum name="AutofillScanCreditCardPrompt"> <int value="0" label="Scan card shown"/> <int value="1" label="Scan card selected"/> <int value="2" label="Some other item selected"/> </enum> -<enum name="AutofillTypeQuality" type="int"> +<enum name="AutofillTypeQuality"> <int value="0" label="Unknown"/> <int value="1" label="Match"/> <int value="2" label="Mismatch"/> @@ -2150,7 +2150,7 @@ <int value="6" label="Mismatch - Unknown Data"/> </enum> -<enum name="AutofillTypeQualityByFieldType" type="int"> +<enum name="AutofillTypeQualityByFieldType"> <int value="0" label="Ambiguous, Unknown"/> <int value="1" label="Ambiguous, Match"/> <int value="2" label="Ambiguous, Mismatch"/> @@ -2216,7 +2216,7 @@ <int value="62" label="Credit Card Verification, Mismatch"/> </enum> -<enum name="AutofillUnmaskPromptEvent" type="int"> +<enum name="AutofillUnmaskPromptEvent"> <int value="0" label="Shown"/> <int value="1" label="Closed with no attempts"/> <int value="2" label="Closed, retriable failure"/> @@ -2235,7 +2235,7 @@ <int value="11" label="Closed, abandon unmasking"/> </enum> -<enum name="AutofillUserHappiness" type="int"> +<enum name="AutofillUserHappiness"> <int value="0" label="Forms loaded"/> <int value="1" label="Deprecated 1"/> <int value="2" label="Deprecated 2"/> @@ -2250,58 +2250,58 @@ <int value="11" label="User edited autofilled field (once)"/> </enum> -<enum name="AutofillWalletAddressConversionType" type="int"> +<enum name="AutofillWalletAddressConversionType"> <int value="0" label="Merged with existing local profile"/> <int value="1" label="Added as a new local profile"/> </enum> -<enum name="AutoLaunchState" type="int"> +<enum name="AutoLaunchState"> <int value="0" label="AUTO_LAUNCH_NONE"/> <int value="1" label="AUTO_LAUNCH_BACKGROUND"/> <int value="2" label="[Deprecated] AUTO_LAUNCH_FOREGROUND"/> <int value="3" label="[Deprecated] AUTO_LAUNCH_FOREGROUND_USELESS"/> </enum> -<enum name="AutoplayBlockedReason" type="int"> +<enum name="AutoplayBlockedReason"> <int value="0" label="Data Saver enabled"/> <int value="1" label="Disabled by setting"/> <int value="2" label="Data Saver and setting"/> </enum> -<enum name="AutoplaySource" type="int"> +<enum name="AutoplaySource"> <int value="0" label="autoplay attribute"/> <int value="1" label="play() method"/> <int value="2" label="dual source"/> </enum> -<enum name="AutoSigninFirstRun" type="int"> +<enum name="AutoSigninFirstRun"> <int value="0" label="No action"/> <int value="1" label="Turn off"/> <int value="2" label="Ok, got it"/> </enum> -<enum name="BackForwardNavigationType" type="int"> +<enum name="BackForwardNavigationType"> <int value="0" label="Fast back navigation with WKBackForwardList"/> <int value="1" label="Slow back navigation"/> <int value="2" label="Fast forward navigation with WKBackForwardList"/> <int value="3" label="Slow forward navigation"/> </enum> -<enum name="BackgroundFetchEventDispatchResult" type="int"> +<enum name="BackgroundFetchEventDispatchResult"> <int value="0" label="Success"/> <int value="1" label="Cannot find worker"/> <int value="2" label="Cannot start worker"/> <int value="3" label="Cannot dispatch the event"/> </enum> -<enum name="BackgroundFetchTrigger" type="int"> +<enum name="BackgroundFetchTrigger"> <int value="0" label="Wake-up of the persistent scheduler"/> <int value="1" label="NTP opened"/> <int value="2" label="Browser foregrounded"/> <int value="3" label="Cold start of the browser"/> </enum> -<enum name="BackgroundModeMenuItem" type="int"> +<enum name="BackgroundModeMenuItem"> <int value="0" label="About"/> <int value="1" label="Task manager"/> <int value="2" label="Background client"/> @@ -2309,14 +2309,14 @@ <int value="4" label="Exit"/> </enum> -<enum name="BackgroundSyncResultPattern" type="int"> +<enum name="BackgroundSyncResultPattern"> <int value="0" label="Success Foreground"/> <int value="1" label="Success Background"/> <int value="2" label="Failed Foreground"/> <int value="3" label="Failed Background"/> </enum> -<enum name="BackgroundSyncStatus" type="int"> +<enum name="BackgroundSyncStatus"> <int value="0" label="Action completed successfully"/> <int value="1" label="Back-end error"/> <int value="2" label="Registration was not found"/> @@ -2325,7 +2325,7 @@ <int value="5" label="Permission denied"/> </enum> -<enum name="BackgroundTaskId" type="int"> +<enum name="BackgroundTaskId"> <int value="0" label="Test task (should not appear)"/> <int value="1" label="Omaha"/> <int value="2" label="GCM Background Task"/> @@ -2336,7 +2336,7 @@ <int value="7" label="Offline page prefetch task"/> </enum> -<enum name="BackgroundTracingState" type="int"> +<enum name="BackgroundTracingState"> <int value="0" label="Scenario activation requested"/> <int value="1" label="Scenario successfully activated"/> <int value="2" label="Trace recording enabled"/> @@ -2349,19 +2349,19 @@ <int value="9" label="Scenario activation failed due to lowres clock"/> </enum> -<enum name="BackingStoreResults" type="int"> +<enum name="BackingStoreResults"> <int value="0" label="Unused"/> <int value="1" label="Success"/> <int value="2" label="Failure"/> </enum> -<enum name="BadMessageReasonChrome" type="int"> +<enum name="BadMessageReasonChrome"> <!-- Generated from chrome/browser/bad_message.h --> <int value="0" label="WRLHH_LOGGING_STOPPED_BAD_STATE"/> </enum> -<enum name="BadMessageReasonContent" type="int"> +<enum name="BadMessageReasonContent"> <!-- Generated from content/browser/bad_message.h --> <int value="0" label="NC_IN_PAGE_NAVIGATION"/> @@ -2541,7 +2541,7 @@ <int value="172" label="RFPH_ILLEGAL_UPLOAD_PARAMS"/> </enum> -<enum name="BadMessageReasonExtensions" type="int"> +<enum name="BadMessageReasonExtensions"> <!-- Generated from extensions/browser/bad_message.h --> <int value="0" label="EOG_BAD_ORIGIN"/> @@ -2556,7 +2556,7 @@ <int value="9" label="EFD_BAD_MESSAGE_WORKER"/> </enum> -<enum name="BadMessageReasonNaCl" type="int"> +<enum name="BadMessageReasonNaCl"> <!-- Generated from components/nacl/browser/bad_message.h --> <int value="0" label="NFH_OPEN_EXECUTABLE_BAD_ROUTING_ID"/> @@ -2564,7 +2564,7 @@ <int value="2" label="NHMF_GET_NEXE_FD_BAD_URL"/> </enum> -<enum name="BadMessageReasonPasswordManager" type="int"> +<enum name="BadMessageReasonPasswordManager"> <!-- Generated from components/password_manager/content/browser/bad_message.h --> <int value="1" label="CPMD_BAD_ORIGIN_FORMS_PARSED"/> @@ -2578,7 +2578,7 @@ label="CPMD_BAD_ORIGIN_SAVE_GENERATION_FIELD_DETECTED_BY_CLASSIFIER"/> </enum> -<enum name="BadSyncDataReason" type="int"> +<enum name="BadSyncDataReason"> <int value="0" label="Bad extension ID"/> <int value="1" label="Bad version"/> <int value="2" label="Bad update URL"/> @@ -2586,7 +2586,7 @@ <int value="4" label="Bad disable reasons"/> </enum> -<enum name="BaseRelocationType" type="int"> +<enum name="BaseRelocationType"> <int value="0" label="IMAGE_REL_BASED_ABSOLUTE"/> <int value="1" label="IMAGE_REL_BASED_HIGH"/> <int value="2" label="IMAGE_REL_BASED_LOW"/> @@ -2600,23 +2600,23 @@ <int value="10" label="IMAGE_REL_BASED_DIR64"/> </enum> -<enum name="BatteryInfoSampleResult" type="int"> +<enum name="BatteryInfoSampleResult"> <int value="0" label="Read"/> <int value="1" label="Good"/> <int value="2" label="Bad"/> </enum> -<enum name="BatteryStatusNumberBatteries" type="int"> +<enum name="BatteryStatusNumberBatteries"> <int value="5" label="5+"/> </enum> -<enum name="BatteryStatusNumberBatteriesWin" type="int"> +<enum name="BatteryStatusNumberBatteriesWin"> <int value="0" label="Unknown"/> <int value="1" label="0"/> <int value="2" label="1+"/> </enum> -<enum name="BiquadFilterType" type="int"> +<enum name="BiquadFilterType"> <int value="0" label="lowpass"/> <int value="1" label="highpass"/> <int value="2" label="bandpass"/> @@ -2627,14 +2627,14 @@ <int value="7" label="allpass"/> </enum> -<enum name="BlacklistedVideoCaptureDeviceNames" type="int"> +<enum name="BlacklistedVideoCaptureDeviceNames"> <int value="0" label="Google GTalk Camera Adapter"/> <int value="1" label="IP Camera"/> <int value="2" label="Cyberlink YouCam Webcam Splitter"/> <int value="3" label="EpocCam Smartphone Wireless Camera"/> </enum> -<enum name="BlacklistSetup" type="int"> +<enum name="BlacklistSetup"> <int value="0" label="Blacklist enabled"/> <int value="1" label="Blacklist ran successfully."/> <int value="2" label="Blacklist failed."/> @@ -2643,7 +2643,7 @@ <int value="5" label="Blacklist disabled."/> </enum> -<enum name="BlobBrokenReason" type="int"> +<enum name="BlobBrokenReason"> <int value="0" label="Unknown"/> <int value="1" label="There is not enough memory to store this blob"/> <int value="2" label="File write failed"/> @@ -2652,7 +2652,7 @@ <int value="5" label="Referenced blob broken"/> </enum> -<enum name="BlobStorageDiskSpaceAdjustment" type="int"> +<enum name="BlobStorageDiskSpaceAdjustment"> <summary> When the blob storage system adjusts its max disk space, it can be frozen, adjusted (near min external disk availability), or normal. These values @@ -2671,7 +2671,7 @@ frozen."/> </enum> -<enum name="BluetoothAvailability" type="int"> +<enum name="BluetoothAvailability"> <int value="0" label="Unexpected error"/> <int value="1" label="Not available"/> <int value="2" label="Available without LE"/> @@ -2679,7 +2679,7 @@ <int value="4" label="Available unknown LE"/> </enum> -<enum name="BluetoothDiscoveryOutcomes" type="int"> +<enum name="BluetoothDiscoveryOutcomes"> <int value="0" label="Success"/> <int value="1" label="Unknown error; used when we could add code to get more detail"/> @@ -2707,7 +2707,7 @@ Discovery."/> </enum> -<enum name="BluetoothGATTErrors" type="int"> +<enum name="BluetoothGATTErrors"> <obsolete> As of 08/2015 this has been replaced with WebBluetoothGATTOperationOutcome. </obsolete> @@ -2717,7 +2717,7 @@ <int value="3" label="Not Paired"/> </enum> -<enum name="BluetoothPairingMethod" type="int"> +<enum name="BluetoothPairingMethod"> <int value="0" label="No user interaction required"/> <int value="1" label="PIN Code requested from user"/> <int value="2" label="Passkey requested from user"/> @@ -2726,7 +2726,7 @@ <int value="5" label="Passkey confirmed on both devices"/> </enum> -<enum name="BluetoothPairingResult" type="int"> +<enum name="BluetoothPairingResult"> <int value="0" label="Success"/> <int value="1" label="Connection already in-progress"/> <int value="2" label="Failed for non-specific reason"/> @@ -2738,13 +2738,13 @@ <int value="8" label="Unknown or unhandler error"/> </enum> -<enum name="BluetoothStatus" type="int"> +<enum name="BluetoothStatus"> <int value="0" label="Disabled"/> <int value="1" label="Enabled"/> <int value="2" label="Unknown"/> </enum> -<enum name="BookmarkLaunchLocation" type="int"> +<enum name="BookmarkLaunchLocation"> <int value="0" label="Attached bookmark bar"/> <int value="1" label="Detached (floating) bookmark bar"/> <int value="2" label="Bookmark bar subfolder"/> @@ -2754,14 +2754,14 @@ <int value="6" label="Omnibox suggestion"/> </enum> -<enum name="BookmarksEntryPoint" type="int"> +<enum name="BookmarksEntryPoint"> <int value="0" label="Accelerator(Ctrl+D)"/> <int value="1" label="Gesture"/> <int value="2" label="Space or Enter"/> <int value="3" label="Mouse click"/> </enum> -<enum name="BookmarksExperimentState" type="int"> +<enum name="BookmarksExperimentState"> <int value="0" label="No experiment"/> <int value="1" label="Experiment enabled (sync)"/> <int value="2" label="Experiment disabled (sync opt out)"/> @@ -2771,788 +2771,788 @@ <int value="6" label="Experiment enabled (sync unknown)"/> </enum> -<enum name="BookmarksOpenAction" type="int"> +<enum name="BookmarksOpenAction"> <int value="0" label="Open in current tab"/> <int value="1" label="Open in new tab"/> <int value="2" label="Open in incognito tab"/> </enum> -<enum name="Boolean" type="int"> +<enum name="Boolean"> <int value="0" label="False"/> <int value="1" label="True"/> </enum> -<enum name="BooleanAbsent" type="int"> +<enum name="BooleanAbsent"> <int value="0" label="Not Absent"/> <int value="1" label="Absent"/> </enum> -<enum name="BooleanAccepted" type="int"> +<enum name="BooleanAccepted"> <int value="0" label="Not Accepted"/> <int value="1" label="Accepted"/> </enum> -<enum name="BooleanAccountChange" type="int"> +<enum name="BooleanAccountChange"> <int value="0" label="Service"/> <int value="1" label="Broadcast"/> </enum> -<enum name="BooleanActivation" type="int"> +<enum name="BooleanActivation"> <int value="0" label="Deactivated"/> <int value="1" label="Activated"/> </enum> -<enum name="BooleanActive" type="int"> +<enum name="BooleanActive"> <int value="0" label="Inactive"/> <int value="1" label="Active"/> </enum> -<enum name="BooleanAllowed" type="int"> +<enum name="BooleanAllowed"> <int value="0" label="Not Allowed"/> <int value="1" label="Allowed"/> </enum> -<enum name="BooleanAttempted" type="int"> +<enum name="BooleanAttempted"> <int value="0" label="Not Attempted"/> <int value="1" label="Attempted"/> </enum> -<enum name="BooleanAvailable" type="int"> +<enum name="BooleanAvailable"> <int value="0" label="Not Available"/> <int value="1" label="Available"/> </enum> -<enum name="BooleanAvoidedNullPointerException" type="int"> +<enum name="BooleanAvoidedNullPointerException"> <int value="0" label="Had NullPointerException"/> <int value="1" label="No exception"/> </enum> -<enum name="BooleanBlocked" type="int"> +<enum name="BooleanBlocked"> <int value="0" label="Not Blocked"/> <int value="1" label="Blocked"/> </enum> -<enum name="BooleanBringToForegroundReason" type="int"> +<enum name="BooleanBringToForegroundReason"> <int value="0" label="Other"/> <int value="1" label="Notification click (within last 5 seconds)"/> </enum> -<enum name="BooleanBroken" type="int"> +<enum name="BooleanBroken"> <int value="0" label="Not Broken"/> <int value="1" label="Broken"/> </enum> -<enum name="BooleanCacheHit" type="int"> +<enum name="BooleanCacheHit"> <int value="0" label="Miss"/> <int value="1" label="Hit"/> </enum> -<enum name="BooleanCanceled" type="int"> +<enum name="BooleanCanceled"> <int value="0" label="Not Canceled"/> <int value="1" label="Canceled"/> </enum> -<enum name="BooleanCanCheckUrl" type="int"> +<enum name="BooleanCanCheckUrl"> <int value="0" label="Skipped"/> <int value="1" label="Can check"/> </enum> -<enum name="BooleanCanvasExpanded" type="int"> +<enum name="BooleanCanvasExpanded"> <int value="0" label="Original canvas dimensions were sufficient"/> <int value="1" label="First image frame dimension were needed"/> </enum> -<enum name="BooleanChanged" type="int"> +<enum name="BooleanChanged"> <int value="0" label="Not changed"/> <int value="1" label="Changed"/> </enum> -<enum name="BooleanChecked" type="int"> +<enum name="BooleanChecked"> <int value="0" label="Not checked"/> <int value="1" label="Checked"/> </enum> -<enum name="BooleanCleared" type="int"> +<enum name="BooleanCleared"> <int value="0" label="Not cleared"/> <int value="1" label="Cleared"/> </enum> -<enum name="BooleanClicked" type="int"> +<enum name="BooleanClicked"> <int value="0" label="Not Clicked"/> <int value="1" label="Clicked"/> </enum> -<enum name="BooleanCloned" type="int"> +<enum name="BooleanCloned"> <int value="0" label="Not cloned"/> <int value="1" label="Cloned"/> </enum> -<enum name="BooleanCloseTimeout" type="int"> +<enum name="BooleanCloseTimeout"> <int value="0" label="Closed normally"/> <int value="1" label="Timed out"/> </enum> -<enum name="BooleanCommonNameMatch" type="int"> +<enum name="BooleanCommonNameMatch"> <int value="0" label="subjectAltName used"/> <int value="1" label="Common Name used"/> </enum> -<enum name="BooleanCompatibilityMode" type="int"> +<enum name="BooleanCompatibilityMode"> <int value="0" label="Not in compatibility mode"/> <int value="1" label="In compatibility mode"/> </enum> -<enum name="BooleanCompleted" type="int"> +<enum name="BooleanCompleted"> <int value="0" label="Not Completed"/> <int value="1" label="Completed"/> </enum> -<enum name="BooleanConnected" type="int"> +<enum name="BooleanConnected"> <int value="0" label="Not Connected"/> <int value="1" label="Connected"/> </enum> -<enum name="BooleanContainedMeCard" type="int"> +<enum name="BooleanContainedMeCard"> <int value="0" label="Did not contain me card."/> <int value="1" label="Contained me card."/> </enum> -<enum name="BooleanCorrupt" type="int"> +<enum name="BooleanCorrupt"> <int value="0" label="Not Corrupt"/> <int value="1" label="Corrupt"/> </enum> -<enum name="BooleanCouldFireImmediately" type="int"> +<enum name="BooleanCouldFireImmediately"> <int value="0" label="Could not fire immediately"/> <int value="1" label="Could fire immediately"/> </enum> -<enum name="BooleanCovered" type="int"> +<enum name="BooleanCovered"> <int value="0" label="Not Covered"/> <int value="1" label="Covered"/> </enum> -<enum name="BooleanCreated" type="int"> +<enum name="BooleanCreated"> <int value="0" label="Not created"/> <int value="1" label="Created"/> </enum> -<enum name="BooleanCredentialsLost" type="int"> +<enum name="BooleanCredentialsLost"> <int value="0" label="Found Credentials"/> <int value="1" label="Missing Credentials"/> </enum> -<enum name="BooleanDataReductionProxy" type="int"> +<enum name="BooleanDataReductionProxy"> <int value="0" label="Not Data Reduction Proxy"/> <int value="1" label="Data Reduction Proxy"/> </enum> -<enum name="BooleanDeclarativeRules" type="int"> +<enum name="BooleanDeclarativeRules"> <int value="0" label="No declarative rules"/> <int value="1" label="Has declarative rules"/> </enum> -<enum name="BooleanDefault" type="int"> +<enum name="BooleanDefault"> <int value="0" label="Not Default"/> <int value="1" label="Default"/> </enum> -<enum name="BooleanDeferred" type="int"> +<enum name="BooleanDeferred"> <int value="0" label="Not deferred"/> <int value="1" label="Deferred"/> </enum> -<enum name="BooleanDelete" type="int"> +<enum name="BooleanDelete"> <int value="0" label="Ignored"/> <int value="1" label="Deleted"/> </enum> -<enum name="BooleanDeletedOrNot" type="int"> +<enum name="BooleanDeletedOrNot"> <int value="0" label="Not deleted"/> <int value="1" label="Deleted"/> </enum> -<enum name="BooleanDeprecatedCiphers" type="int"> +<enum name="BooleanDeprecatedCiphers"> <int value="0" label="Deprecated ciphers disabled"/> <int value="1" label="Deprecated ciphers enabled"/> </enum> -<enum name="BooleanDidEvict" type="int"> +<enum name="BooleanDidEvict"> <int value="0" label="Did not evict"/> <int value="1" label="Did evict"/> </enum> -<enum name="BooleanDidFallBack" type="int"> +<enum name="BooleanDidFallBack"> <int value="0" label="Did not fall back"/> <int value="1" label="Did fall back"/> </enum> -<enum name="BooleanDidScalePage" type="int"> +<enum name="BooleanDidScalePage"> <int value="0" label="User did not change scale"/> <int value="1" label="User did change scale"/> </enum> -<enum name="BooleanDuplicate" type="int"> +<enum name="BooleanDuplicate"> <int value="0" label="Not Duplicate"/> <int value="1" label="Duplicate"/> </enum> -<enum name="BooleanEmpty" type="int"> +<enum name="BooleanEmpty"> <int value="0" label="Not Empty"/> <int value="1" label="Empty"/> </enum> -<enum name="BooleanEnabled" type="int"> +<enum name="BooleanEnabled"> <int value="0" label="Disabled"/> <int value="1" label="Enabled"/> </enum> -<enum name="BooleanEqual" type="int"> +<enum name="BooleanEqual"> <int value="0" label="Not Equal"/> <int value="1" label="Equal"/> </enum> -<enum name="BooleanError" type="int"> +<enum name="BooleanError"> <int value="0" label="No Error"/> <int value="1" label="Error"/> </enum> -<enum name="BooleanEverWorked" type="int"> +<enum name="BooleanEverWorked"> <int value="0" label="Has never worked"/> <int value="1" label="Has worked at least once"/> </enum> -<enum name="BooleanExists" type="int"> +<enum name="BooleanExists"> <int value="0" label="Does not exist"/> <int value="1" label="Exists"/> </enum> -<enum name="BooleanExpired" type="int"> +<enum name="BooleanExpired"> <int value="0" label="Unexpired"/> <int value="1" label="Expired"/> </enum> -<enum name="BooleanForced" type="int"> +<enum name="BooleanForced"> <int value="0" label="Not forced"/> <int value="1" label="Forced"/> </enum> -<enum name="BooleanForceDisabled" type="int"> +<enum name="BooleanForceDisabled"> <int value="0" label="Not Force Disabled"/> <int value="1" label="Force Disabled"/> </enum> -<enum name="BooleanForeground" type="int"> +<enum name="BooleanForeground"> <int value="0" label="Background"/> <int value="1" label="Foreground"/> </enum> -<enum name="BooleanForegroundNotification" type="int"> +<enum name="BooleanForegroundNotification"> <int value="0" label="Background Notification"/> <int value="1" label="Foreground Notification"/> </enum> -<enum name="BooleanForemost" type="int"> +<enum name="BooleanForemost"> <int value="0" label="Tab was not foremost"/> <int value="1" label="Tab was foremost"/> </enum> -<enum name="BooleanFormatChanged" type="int"> +<enum name="BooleanFormatChanged"> <int value="0" label="Any Codec Initialized"/> <int value="1" label="Missing FORMAT_CHANGED message"/> </enum> -<enum name="BooleanFormManager" type="int"> +<enum name="BooleanFormManager"> <int value="0" label="Has Form Manager"/> <int value="1" label="Lacks Form Manager"/> </enum> -<enum name="BooleanFrameAsOverlay" type="int"> +<enum name="BooleanFrameAsOverlay"> <int value="0" label="Frame was not allow_overlay"/> <int value="1" label="Frame was allow_overlay"/> </enum> -<enum name="BooleanFromAddressBook" type="int"> +<enum name="BooleanFromAddressBook"> <int value="0" label="Not From Address Book"/> <int value="1" label="From Address Book"/> </enum> -<enum name="BooleanFromHTTPCache" type="int"> +<enum name="BooleanFromHTTPCache"> <int value="0" label="Downloaded from network"/> <int value="1" label="HTTP cache hit"/> </enum> -<enum name="BooleanGAIAWebViewFlow" type="int"> +<enum name="BooleanGAIAWebViewFlow"> <int value="0" label="iframe-based flow"/> <int value="1" label="WebView-based flow"/> </enum> -<enum name="BooleanHadAddress" type="int"> +<enum name="BooleanHadAddress"> <int value="0" label="Did not have address."/> <int value="1" label="Had address."/> </enum> -<enum name="BooleanHadBlankText" type="int"> +<enum name="BooleanHadBlankText"> <int value="0" label="Did not have blank text"/> <int value="1" label="Had blank text"/> </enum> -<enum name="BooleanHadEmail" type="int"> +<enum name="BooleanHadEmail"> <int value="0" label="Did not have email."/> <int value="1" label="Had email."/> </enum> -<enum name="BooleanHadName" type="int"> +<enum name="BooleanHadName"> <int value="0" label="Did not have name."/> <int value="1" label="Had name."/> </enum> -<enum name="BooleanHadPhoneNumber" type="int"> +<enum name="BooleanHadPhoneNumber"> <int value="0" label="Did not have phone number."/> <int value="1" label="Had phone number."/> </enum> -<enum name="BooleanHadPredictions" type="int"> +<enum name="BooleanHadPredictions"> <int value="0" label="No predictions"/> <int value="1" label="Has predictions"/> </enum> -<enum name="BooleanHandshakeConfirmed" type="int"> +<enum name="BooleanHandshakeConfirmed"> <int value="0" label="Handshake not confirmed"/> <int value="1" label="Handshake confirmed"/> </enum> -<enum name="BooleanHardwareAccelerated" type="int"> +<enum name="BooleanHardwareAccelerated"> <int value="0" label="Not hardware accelerated"/> <int value="1" label="Hardware accelerated"/> </enum> -<enum name="BooleanHasCollapseKey" type="int"> +<enum name="BooleanHasCollapseKey"> <int value="0" label="No collapse_key"/> <int value="1" label="Has collapse_key"/> </enum> -<enum name="BooleanHasCrc" type="int"> +<enum name="BooleanHasCrc"> <int value="0" label="No CRC"/> <int value="1" label="Has CRC"/> </enum> -<enum name="BooleanHasDistilledData" type="int"> +<enum name="BooleanHasDistilledData"> <int value="0" label="No distilled data"/> <int value="1" label="Has distilled data"/> </enum> -<enum name="BooleanHasPath" type="int"> +<enum name="BooleanHasPath"> <int value="0" label="No path"/> <int value="1" label="Has path"/> </enum> -<enum name="BooleanHasPlayed" type="int"> +<enum name="BooleanHasPlayed"> <int value="0" label="Never played"/> <int value="1" label="Played"/> </enum> -<enum name="BooleanHasSeekPenalty" type="int"> +<enum name="BooleanHasSeekPenalty"> <int value="0" label="Has no seek penalty (e.g. is flash memory)"/> <int value="1" label="Has seek penalty (e.g. spinning disk)"/> </enum> -<enum name="BooleanHit" type="int"> +<enum name="BooleanHit"> <int value="0" label="Not_reached"/> <int value="1" label="Hit"/> </enum> -<enum name="BooleanHttps" type="int"> +<enum name="BooleanHttps"> <int value="0" label="HTTP"/> <int value="1" label="HTTPS"/> </enum> -<enum name="BooleanIgnored" type="int"> +<enum name="BooleanIgnored"> <int value="0" label="Not ignored"/> <int value="1" label="Ignored"/> </enum> -<enum name="BooleanInappropriateFallback" type="int"> +<enum name="BooleanInappropriateFallback"> <int value="0" label="Handshake successful"/> <int value="1" label="inappropriate_fallback alert"/> </enum> -<enum name="BooleanIncognito" type="int"> +<enum name="BooleanIncognito"> <int value="0" label="Not Incognito"/> <int value="1" label="Incognito"/> </enum> -<enum name="BooleanInForeground" type="int"> +<enum name="BooleanInForeground"> <int value="0" label="Background"/> <int value="1" label="Foreground"/> </enum> -<enum name="BooleanInvalid" type="int"> +<enum name="BooleanInvalid"> <int value="0" label="Valid"/> <int value="1" label="Invalid"/> </enum> -<enum name="BooleanIsLastSharedAppInfoRetrieved" type="int"> +<enum name="BooleanIsLastSharedAppInfoRetrieved"> <int value="0" label="Not retrieved"/> <int value="1" label="Retrieved"/> </enum> -<enum name="BooleanIsMalware" type="int"> +<enum name="BooleanIsMalware"> <int value="0" label="Not malware"/> <int value="1" label="Is malware"/> </enum> -<enum name="BooleanIsMobileOptimized" type="int"> +<enum name="BooleanIsMobileOptimized"> <int value="0" label="Not mobile optimized web page"/> <int value="1" label="Mobile optimized web page"/> </enum> -<enum name="BooleanIsPhishing" type="int"> +<enum name="BooleanIsPhishing"> <int value="0" label="Not phishing"/> <int value="1" label="Is phishing"/> </enum> -<enum name="BooleanIsShared" type="int"> +<enum name="BooleanIsShared"> <int value="0" label="Not Shared"/> <int value="1" label="Is Shared"/> </enum> -<enum name="BooleanLoaded" type="int"> +<enum name="BooleanLoaded"> <int value="0" label="Not loaded"/> <int value="1" label="Loaded"/> </enum> -<enum name="BooleanMainFrame" type="int"> +<enum name="BooleanMainFrame"> <int value="0" label="Subframe"/> <int value="1" label="Main frame"/> </enum> -<enum name="BooleanMatched" type="int"> +<enum name="BooleanMatched"> <int value="0" label="Not matched"/> <int value="1" label="Matched"/> </enum> -<enum name="BooleanMatchedBadIp" type="int"> +<enum name="BooleanMatchedBadIp"> <int value="0" label="Not matched"/> <int value="1" label="Matched"/> </enum> -<enum name="BooleanMigrated" type="int"> +<enum name="BooleanMigrated"> <int value="0" label="Not migrated"/> <int value="1" label="Migrated"/> </enum> -<enum name="BooleanMissingCallbacks" type="int"> +<enum name="BooleanMissingCallbacks"> <int value="0" label="No missing callbacks"/> <int value="1" label="Had missing callbacks"/> </enum> -<enum name="BooleanMissingFromDiskCache" type="int"> +<enum name="BooleanMissingFromDiskCache"> <int value="0" label="Has data in disk cache"/> <int value="1" label="Missing data in disk cache"/> </enum> -<enum name="BooleanNativeNotifications" type="int"> +<enum name="BooleanNativeNotifications"> <int value="0" label="Using Chrome notifications"/> <int value="1" label="Using native notifications"/> </enum> -<enum name="BooleanNavPreloadFinishedFirst" type="int"> +<enum name="BooleanNavPreloadFinishedFirst"> <int value="0" label="Worker preparation finished first"/> <int value="1" label="Navigation preload response arrived first"/> </enum> -<enum name="BooleanNeedsClearing" type="int"> +<enum name="BooleanNeedsClearing"> <int value="0" label="Doesn't need clearing"/> <int value="1" label="Needs to be clearred"/> </enum> -<enum name="BooleanNullStream" type="int"> +<enum name="BooleanNullStream"> <int value="0" label="Stream is not a nullptr"/> <int value="1" label="Stream is a nullptr"/> </enum> -<enum name="BooleanNullVisitor" type="int"> +<enum name="BooleanNullVisitor"> <int value="0" label="Connection's visitor is not a nullptr"/> <int value="1" label="Connection's visitor is a nullptr"/> </enum> -<enum name="BooleanOnBattery" type="int"> +<enum name="BooleanOnBattery"> <int value="0" label="Not on battery"/> <int value="1" label="On Battery"/> </enum> -<enum name="BooleanOrphan" type="int"> +<enum name="BooleanOrphan"> <int value="0" label="Non-orphan"/> <int value="1" label="Orphan"/> </enum> -<enum name="BooleanOverlaySupported" type="int"> +<enum name="BooleanOverlaySupported"> <int value="0" label="No overlays supported"/> <int value="1" label="Supports overlays"/> </enum> -<enum name="BooleanOverlayUsage" type="int"> +<enum name="BooleanOverlayUsage"> <int value="0" label="No overlay"/> <int value="1" label="Overlay"/> </enum> -<enum name="BooleanPanelWasOpen" type="int"> +<enum name="BooleanPanelWasOpen"> <int value="0" label="Panel was closed"/> <int value="1" label="Panel was open"/> </enum> -<enum name="BooleanPending" type="int"> +<enum name="BooleanPending"> <int value="0" label="Decided"/> <int value="1" label="Pending"/> </enum> -<enum name="BooleanPersisted" type="int"> +<enum name="BooleanPersisted"> <int value="0" label="Not persisted"/> <int value="1" label="Persisted"/> </enum> -<enum name="BooleanPinned" type="int"> +<enum name="BooleanPinned"> <int value="0" label="Not Pinned"/> <int value="1" label="Pinned"/> </enum> -<enum name="BooleanPopulated" type="int"> +<enum name="BooleanPopulated"> <int value="0" label="Not populated"/> <int value="1" label="Populated"/> </enum> -<enum name="BooleanPreferred" type="int"> +<enum name="BooleanPreferred"> <int value="0" label="Not Preferred"/> <int value="1" label="Preferred"/> </enum> -<enum name="BooleanPresent" type="int"> +<enum name="BooleanPresent"> <int value="0" label="Not Present"/> <int value="1" label="Present"/> </enum> -<enum name="BooleanProfileSignedIn" type="int"> +<enum name="BooleanProfileSignedIn"> <int value="0" label="Profile was not Signed In"/> <int value="1" label="Profile was Signed In"/> </enum> -<enum name="BooleanRaced" type="int"> +<enum name="BooleanRaced"> <int value="0" label="Did Not Race"/> <int value="1" label="Raced"/> </enum> -<enum name="BooleanRebooted" type="int"> +<enum name="BooleanRebooted"> <int value="0" label="Has not rebooted"/> <int value="1" label="Rebooted"/> </enum> -<enum name="BooleanReceived" type="int"> +<enum name="BooleanReceived"> <int value="0" label="Not Received"/> <int value="1" label="Received"/> </enum> -<enum name="BooleanRecorded" type="int"> +<enum name="BooleanRecorded"> <int value="0" label="Not Recorded"/> <int value="1" label="Recorded"/> </enum> -<enum name="BooleanRegistered" type="int"> +<enum name="BooleanRegistered"> <int value="0" label="Not Registered"/> <int value="1" label="Registered"/> </enum> -<enum name="BooleanRegistrationIsDuplicate" type="int"> +<enum name="BooleanRegistrationIsDuplicate"> <int value="0" label="Registration is not a duplicate"/> <int value="1" label="Registration is a duplicate"/> </enum> -<enum name="BooleanReported" type="int"> +<enum name="BooleanReported"> <int value="0" label="Not reported"/> <int value="1" label="Reported"/> </enum> -<enum name="BooleanRequested" type="int"> +<enum name="BooleanRequested"> <int value="0" label="Not requested"/> <int value="1" label="Requested"/> </enum> -<enum name="BooleanRequired" type="int"> +<enum name="BooleanRequired"> <int value="0" label="Not required"/> <int value="1" label="Required"/> </enum> -<enum name="BooleanReset" type="int"> +<enum name="BooleanReset"> <int value="0" label="Not reset"/> <int value="1" label="Reset"/> </enum> -<enum name="BooleanRestoredURL" type="int"> +<enum name="BooleanRestoredURL"> <int value="0" label="Default frame src URL"/> <int value="1" label="Different URL"/> </enum> -<enum name="BooleanReused" type="int"> +<enum name="BooleanReused"> <int value="0" label="Not Reused"/> <int value="1" label="Reused"/> </enum> -<enum name="BooleanRevoked" type="int"> +<enum name="BooleanRevoked"> <int value="0" label="Not revoked"/> <int value="1" label="Revoked"/> </enum> -<enum name="BooleanSecure" type="int"> +<enum name="BooleanSecure"> <int value="0" label="Insecure"/> <int value="1" label="Secure"/> </enum> -<enum name="BooleanSelected" type="int"> +<enum name="BooleanSelected"> <int value="0" label="No selection"/> <int value="1" label="Selected"/> </enum> -<enum name="BooleanShareGroup" type="int"> +<enum name="BooleanShareGroup"> <int value="0" label="No share group"/> <int value="1" label="Using share group"/> </enum> -<enum name="BooleanShown" type="int"> +<enum name="BooleanShown"> <int value="0" label="Not Shown"/> <int value="1" label="Shown"/> </enum> -<enum name="BooleanSkipped" type="int"> +<enum name="BooleanSkipped"> <int value="0" label="Not skipped"/> <int value="1" label="Skipped"/> </enum> -<enum name="BooleanStale" type="int"> +<enum name="BooleanStale"> <int value="0" label="Fresh"/> <int value="1" label="Stale"/> </enum> -<enum name="BooleanStartedCompleted" type="int"> +<enum name="BooleanStartedCompleted"> <int value="0" label="Started"/> <int value="1" label="Completed"/> </enum> -<enum name="BooleanStreamed" type="int"> +<enum name="BooleanStreamed"> <int value="0" label="Not streamed"/> <int value="1" label="Streamed"/> </enum> -<enum name="BooleanSuccess" type="int"> +<enum name="BooleanSuccess"> <int value="0" label="Failure"/> <int value="1" label="Success"/> </enum> -<enum name="BooleanSupported" type="int"> +<enum name="BooleanSupported"> <int value="0" label="Not Supported"/> <int value="1" label="Supported"/> </enum> -<enum name="BooleanSuppressed" type="int"> +<enum name="BooleanSuppressed"> <int value="0" label="No suppressions"/> <int value="1" label="Suppressed"/> </enum> -<enum name="BooleanTabDiscard" type="int"> +<enum name="BooleanTabDiscard"> <int value="0" label="Memory OK, no discards"/> <int value="1" label="Memory low, tabs discarded"/> </enum> -<enum name="BooleanTabDiscardFastShutdown" type="int"> +<enum name="BooleanTabDiscardFastShutdown"> <int value="0" label="Fast shutdown failed"/> <int value="1" label="Fast shutdown succeeded"/> </enum> -<enum name="BooleanTablet" type="int"> +<enum name="BooleanTablet"> <int value="0" label="Non tablet"/> <int value="1" label="Tablet"/> </enum> -<enum name="BooleanTerminated" type="int"> +<enum name="BooleanTerminated"> <int value="0" label="Not terminated"/> <int value="1" label="Terminated"/> </enum> -<enum name="BooleanTiled" type="int"> +<enum name="BooleanTiled"> <int value="0" label="Not tiled"/> <int value="1" label="Tiled"/> </enum> -<enum name="BooleanTimedOut" type="int"> +<enum name="BooleanTimedOut"> <int value="0" label="Did not time out"/> <int value="1" label="Timed out"/> </enum> -<enum name="BooleanTooMany" type="int"> +<enum name="BooleanTooMany"> <int value="0" label="Correct"/> <int value="1" label="Too many"/> </enum> -<enum name="BooleanTranslate" type="int"> +<enum name="BooleanTranslate"> <int value="0" label="Not Translated"/> <int value="1" label="Translated"/> </enum> -<enum name="BooleanUninstallable" type="int"> +<enum name="BooleanUninstallable"> <int value="0" label="Not uninstallable"/> <int value="1" label="Uninstallable"/> </enum> -<enum name="BooleanUnknown" type="int"> +<enum name="BooleanUnknown"> <int value="0" label="Known"/> <int value="1" label="Unknown"/> </enum> -<enum name="BooleanUsage" type="int"> +<enum name="BooleanUsage"> <int value="0" label="Not Used"/> <int value="1" label="Used"/> </enum> -<enum name="BooleanValid" type="int"> +<enum name="BooleanValid"> <int value="0" label="Invalid"/> <int value="1" label="Valid"/> </enum> -<enum name="BooleanValidHashSum" type="int"> +<enum name="BooleanValidHashSum"> <int value="0" label="Invalid hash sum"/> <int value="1" label="Valid hash sum"/> </enum> -<enum name="BooleanValidKeyExists" type="int"> +<enum name="BooleanValidKeyExists"> <int value="0" label="No Valid Cached Key Found"/> <int value="1" label="Valid Cached Key Found"/> </enum> -<enum name="BooleanVirtualContext" type="int"> +<enum name="BooleanVirtualContext"> <int value="0" label="Real context encountered"/> <int value="1" label="Virtual context encountered"/> </enum> -<enum name="BooleanVisible" type="int"> +<enum name="BooleanVisible"> <int value="0" label="Not visible"/> <int value="1" label="Visible"/> </enum> -<enum name="BooleanWasFast" type="int"> +<enum name="BooleanWasFast"> <int value="0" label="Slow"/> <int value="1" label="Fast"/> </enum> -<enum name="BooleanWasted" type="int"> +<enum name="BooleanWasted"> <int value="0" label="Not wasted"/> <int value="1" label="Wasted"/> </enum> -<enum name="BooleanWiped" type="int"> +<enum name="BooleanWiped"> <int value="0" label="Re-enabled"/> <int value="1" label="Wiped out"/> </enum> -<enum name="BoringSSLReasonCode" type="int"> +<enum name="BoringSSLReasonCode"> <obsolete> Removed in March 2016. </obsolete> @@ -3562,7 +3562,7 @@ </details> </enum> -<enum name="BrokenAlternateProtocolLocation" type="int"> +<enum name="BrokenAlternateProtocolLocation"> <int value="0" label="HTTP_STREAM_FACTORY_IMPL_JOB"/> <int value="1" label="QUIC_STREAM_FACTORY"/> <int value="2" label="HTTP_STREAM_FACTORY_IMPL_JOB_ALT"/> @@ -3570,13 +3570,13 @@ <int value="4" label="QUIC_HTTP_STREAM"/> </enum> -<enum name="BrotliFilterDecodingStatus" type="int"> +<enum name="BrotliFilterDecodingStatus"> <int value="0" label="In progress"/> <int value="1" label="Done"/> <int value="2" label="Error"/> </enum> -<enum name="BrotliFilterErrorCode" type="int"> +<enum name="BrotliFilterErrorCode"> <int value="0" label="NO_ERROR"/> <int value="1" label="FORMAT_EXUBERANT_NIBBLE"/> <int value="2" label="FORMAT_RESERVED"/> @@ -3616,7 +3616,7 @@ <int value="36" label="UNREACHABLE_6"/> </enum> -<enum name="BubbleType" type="int"> +<enum name="BubbleType"> <int value="0" label="Unknown Bubble"/> <int value="1" label="Mock Bubble"/> <int value="10" label="Extension Installed Bubble"/> @@ -3625,7 +3625,7 @@ <int value="31" label="Chooser Permissions Bubble"/> </enum> -<enum name="CacheResult" type="int"> +<enum name="CacheResult"> <int value="0" label="MEMORY_CACHE_HIT"/> <int value="1" label="DISK_CACHE_HIT"/> <int value="2" label="DISK_CACHE_ENTRY_CORRUPT"/> @@ -3633,7 +3633,7 @@ <int value="4" label="CACHE_MISS"/> </enum> -<enum name="CALayerResult" type="int"> +<enum name="CALayerResult"> <int value="0" label="Success"/> <int value="1" label="Unknown failure"/> <int value="2" label="IOSurface resource not overlay candidate"/> @@ -3662,12 +3662,12 @@ <int value="23" label="Too many RenderPassDrawQuads."/> </enum> -<enum name="CanMakePaymentUsage" type="int"> +<enum name="CanMakePaymentUsage"> <int value="0" label="Used"/> <int value="1" label="Not Used"/> </enum> -<enum name="CanvasContextType" type="int"> +<enum name="CanvasContextType"> <int value="0" label="2d"/> <int value="1" label="(obsolete) webkit-3d"/> <int value="2" label="experimental-webgl"/> @@ -3676,7 +3676,7 @@ <int value="5" label="bitmaprenderer"/> </enum> -<enum name="CanvasContextUsage" type="int"> +<enum name="CanvasContextUsage"> <int value="0" label="CanvasCreated"/> <int value="1" label="GPUAccelerated2DCanvasImageBufferCreated"/> <int value="2" label="DisplayList2DCanvasImageBufferCreated"/> @@ -3689,7 +3689,7 @@ <int value="10" label="GPUAccelerated2DCanvasSurfaceCreationFailed"/> </enum> -<enum name="CanvasDisplayListFallbackReason" type="int"> +<enum name="CanvasDisplayListFallbackReason"> <int value="0" label="Unknown (Should not be seen in production)."/> <int value="1" label="Canvas not cleared between consecutive frames."/> <int value="2" @@ -3729,7 +3729,7 @@ <int value="29" label="Acquiring snapshot for createImageBitmap()."/> </enum> -<enum name="CanvasGPUAccelerated2DCanvasDisableDeferralReason" type="int"> +<enum name="CanvasGPUAccelerated2DCanvasDisableDeferralReason"> <int value="0" label="Unknown (Should not be seen in production)."/> <int value="1" label="Canvas not cleared between consecutive frames."/> <int value="2" @@ -3741,7 +3741,7 @@ <int value="7" label="Running on low-end device"/> </enum> -<enum name="CanvasHibernationEvent" type="int"> +<enum name="CanvasHibernationEvent"> <int value="0" label="HibernationScheduled"/> <int value="1" label="HibernationAbortedDueToDestructionWhileHibernatePending"/> @@ -3757,7 +3757,7 @@ <int value="11" label="HibernationAbortedBecauseNoSurface"/> </enum> -<enum name="CAPSUpdaterStep" type="int"> +<enum name="CAPSUpdaterStep"> <obsolete> Deprecated 08/2016 with removal of Chrome Crash Service component. </obsolete> @@ -3767,12 +3767,12 @@ <int value="3" label="CAPS Service started"/> </enum> -<enum name="CaptivePortalBlockingPageEvent" type="int"> +<enum name="CaptivePortalBlockingPageEvent"> <int value="0" label="SHOW_ALL"/> <int value="1" label="OPEN_LOGIN_PAGE"/> </enum> -<enum name="CaptivePortalDetectResult" type="int"> +<enum name="CaptivePortalDetectResult"> <int value="0" label="INTERNET_CONNECTED"/> <int value="1" label="NO_RESPONSE"/> <int value="2" label="BEHIND_CAPTIVE_PORTAL"/> @@ -3784,18 +3784,18 @@ <int value="8" label="BEHIND_CAPTIVE_PORTAL_HTTPS_LANDING_URL_IP_ADDRESS"/> </enum> -<enum name="CaptivePortalNotificationStatus" type="int"> +<enum name="CaptivePortalNotificationStatus"> <int value="0" label="DISPLAYED"/> <int value="1" label="ERROR"/> </enum> -<enum name="CaptivePortalNotificationUserAction" type="int"> +<enum name="CaptivePortalNotificationUserAction"> <int value="0" label="CLICKED"/> <int value="1" label="CLOSED"/> <int value="2" label="IGNORED"/> </enum> -<enum name="CaptivePortalStatus" type="int"> +<enum name="CaptivePortalStatus"> <int value="0" label="UNKNOWN"/> <int value="1" label="OFFLINE"/> <int value="2" label="ONLINE"/> @@ -3803,7 +3803,7 @@ <int value="4" label="PROXY_AUTH_REQUIRED"/> </enum> -<enum name="CaptureApiMac" type="int"> +<enum name="CaptureApiMac"> <obsolete> Deprecated as of 04/2016. </obsolete> @@ -3814,7 +3814,7 @@ <int value="4" label="AVFoundation is enabled and is loaded succesfully"/> </enum> -<enum name="CapturePixelFormat" type="int"> +<enum name="CapturePixelFormat"> <obsolete> Deprecated as of 08/2015. </obsolete> @@ -3830,7 +3830,7 @@ <int value="9" label="TEXTURE"/> </enum> -<enum name="CaptureStartupResult" type="int"> +<enum name="CaptureStartupResult"> <obsolete> Deprecated as of 02/2017. </obsolete> @@ -3844,33 +3844,33 @@ <int value="7" label="Failed to open low latency stream"/> </enum> -<enum name="CastCertificateStatus" type="int"> +<enum name="CastCertificateStatus"> <int value="0" label="OK"/> <int value="1" label="InvalidCrl"/> <int value="2" label="CertVerificationFailed"/> <int value="3" label="CertRevoked"/> </enum> -<enum name="CastNonceStatus" type="int"> +<enum name="CastNonceStatus"> <int value="0" label="Match"/> <int value="1" label="Mismatch"/> <int value="2" label="Missing"/> </enum> -<enum name="CastOverlayEvents" type="int"> +<enum name="CastOverlayEvents"> <int value="0" label="Created"/> <int value="1" label="Shown"/> <int value="2" label="Clicked"/> </enum> -<enum name="CastPlayBackState" type="int"> +<enum name="CastPlayBackState"> <int value="0" label="YT_PLAYER_SUCCESS"/> <int value="1" label="YT_PLAYER_FAILURE"/> <int value="2" label="DEFAULT_PLAYER_SUCCESS"/> <int value="3" label="DEFAULT_PLAYER_FAILURE"/> </enum> -<enum name="CatSixtyFour" type="int"> +<enum name="CatSixtyFour"> <int value="0" label="Saber-Toothed Cat (<10.6), 32-bit (?)"/> <int value="1" label="Saber-Toothed Cat (<10.6), 64-bit (?)"/> <int value="2" label="Snow Leopard (10.6), 32-bit"/> @@ -3894,7 +3894,7 @@ <int value="20" label="FutureCat (>10.10), 8-bit (?)"/> </enum> -<enum name="CdmPromiseResult" type="int"> +<enum name="CdmPromiseResult"> <int value="0" label="Success"/> <int value="1" label="NotSupportedError"/> <int value="2" label="InvalidStateError"/> @@ -3905,7 +3905,7 @@ <int value="7" label="OutputError"/> </enum> -<enum name="CertificateChainPosition" type="int"> +<enum name="CertificateChainPosition"> <obsolete> Deprecated as of 01/2016. CertCacheTrial has been removed. https://crbug.com/522312 @@ -3913,7 +3913,7 @@ <int value="0" label="Root Certificate"/> </enum> -<enum name="CertificateTransparencyDnsQueryStatus" type="int"> +<enum name="CertificateTransparencyDnsQueryStatus"> <int value="0" label="SUCCESS"/> <int value="1" label="FAILED_UNKNOWN"/> <int value="2" label="FAILED_NAME_RESOLUTION"/> @@ -3921,7 +3921,7 @@ <int value="4" label="FAILED_INCLUSION_PROOF_MALFORMED"/> </enum> -<enum name="ChannelLayout" type="int"> +<enum name="ChannelLayout"> <int value="0" label="CHANNEL_LAYOUT_NONE"/> <int value="1" label="CHANNEL_LAYOUT_UNSUPPORTED"/> <int value="2" label="CHANNEL_LAYOUT_MONO"/> @@ -3954,14 +3954,14 @@ <int value="29" label="CHANNEL_LAYOUT_DISCRETE"/> </enum> -<enum name="CheckCRCResult" type="int"> +<enum name="CheckCRCResult"> <int value="0" label="Stream was never read to end"/> <int value="1" label="CRC check not done"/> <int value="2" label="CRC check done"/> <int value="3" label="Stream was never read at all"/> </enum> -<enum name="ChromeChannelForHistogram" type="int"> +<enum name="ChromeChannelForHistogram"> <int value="0" label="UNKNOWN"/> <int value="1" label="CANARY"/> <int value="2" label="DEV"/> @@ -3969,7 +3969,7 @@ <int value="4" label="STABLE"/> </enum> -<enum name="ChromeDownloadCountType" type="int"> +<enum name="ChromeDownloadCountType"> <int value="0" label="Initiated by Navigation (Obsolete)"/> <int value="1" label="Initiated by Context Menu (Obsolete)"/> <int value="2" label="Initiated by WebStore Installer (Obsolete)"/> @@ -3977,7 +3977,7 @@ <int value="4" label="Blocked by Throttling"/> </enum> -<enum name="ChromeDownloadSource" type="int"> +<enum name="ChromeDownloadSource"> <int value="0" label="Initiated by Navigation"/> <int value="1" label="Initiated by Context Menu"/> <int value="2" label="Initiated by WebStore Installer"/> @@ -3985,20 +3985,20 @@ <int value="4" label="Initiated by Plugin Installer"/> </enum> -<enum name="ChromeHomeOpenReason" type="int"> +<enum name="ChromeHomeOpenReason"> <int value="0" label="Swipe"/> <int value="1" label="Omnibox Focus"/> <int value="2" label="New Tab Creation"/> <int value="3" label="Expand Button Pressed"/> </enum> -<enum name="ChromeNotifierServiceActionType" type="int"> +<enum name="ChromeNotifierServiceActionType"> <int value="0" label="Unknown"/> <int value="1" label="First service enabled"/> <int value="2" label="First service disabled"/> </enum> -<enum name="ChromeOSColorProfile" type="int"> +<enum name="ChromeOSColorProfile"> <summary>See ui/display/display_constants.h for the variation.</summary> <int value="0" label="Standard"/> <int value="1" label="Dynamic"/> @@ -4006,13 +4006,13 @@ <int value="3" label="Reading"/> </enum> -<enum name="ChromeOSMachineIdReason" type="int"> +<enum name="ChromeOSMachineIdReason"> <int value="0" label="Unknown"/> <int value="1" label="Network"/> <int value="2" label="Periodic"/> </enum> -<enum name="ChromeOSPlatformVerificationExpiryStatus" type="int"> +<enum name="ChromeOSPlatformVerificationExpiryStatus"> <summary> Possible results of a platform verification expiry check. See chrome/browser/chromeos/attestation/platform_verification.cc. @@ -4024,7 +4024,7 @@ <int value="4" label="Invalid X.509"/> </enum> -<enum name="ChromeOSPlatformVerificationResult" type="int"> +<enum name="ChromeOSPlatformVerificationResult"> <summary> Possible results of a platform verification attempt. See chrome/browser/chromeos/attestation/platform_verification.h. @@ -4037,7 +4037,7 @@ <int value="5" label="Timeout"/> </enum> -<enum name="ChromeOSUserImageId" type="int"> +<enum name="ChromeOSUserImageId"> <summary> Indices of the default images as defined in chrome/browser/chromeos/login/default_user_images.cc. The last three values @@ -4068,19 +4068,19 @@ <int value="22" label="Profile image"/> </enum> -<enum name="ChromiumAndroidLinkerBrowserState" type="int"> +<enum name="ChromiumAndroidLinkerBrowserState"> <int value="0" label="Normal, Random Address Load"/> <int value="1" label="Low memory, Fixed Address Load Success"/> <int value="2" label="Low memory, Fixed Address Load Failure"/> </enum> -<enum name="ChromiumAndroidLinkerRendererState" type="int"> +<enum name="ChromiumAndroidLinkerRendererState"> <int value="0" label="Fixed Address Load Success"/> <int value="1" label="Fixed Address Load Failure"/> <int value="2" label="Fixed Address Load Not Attempted"/> </enum> -<enum name="CLD2LanguageCode" type="int"> +<enum name="CLD2LanguageCode"> <summary> See Language in third_party/cld_2/src/internal/generated_language.h. </summary> @@ -4700,7 +4700,7 @@ <int value="613" label="X_Takri"/> </enum> -<enum name="CLD3LanguageCode" type="int"> +<enum name="CLD3LanguageCode"> <summary> Hash values for the languages supported by CLD3. Each of these values is computed by casting the output of base::HashMetricName(language_string_id) @@ -4819,12 +4819,12 @@ <int value="2119087611" label="nl"/> </enum> -<enum name="ClearBrowsingDataTab" type="int"> +<enum name="ClearBrowsingDataTab"> <int value="0" label="Basic"/> <int value="1" label="Advanced"/> </enum> -<enum name="ClearDataSiteBlacklistCrossedReason" type="int"> +<enum name="ClearDataSiteBlacklistCrossedReason"> <int value="0" label="Durable"/> <int value="1" label="Notifications"/> <int value="2" label="Engagement"/> @@ -4835,7 +4835,7 @@ <int value="7" label="Unknown"/> </enum> -<enum name="ClearServerDataEvents" type="int"> +<enum name="ClearServerDataEvents"> <int value="0" label="Clear server data started"/> <int value="1" label="Catchup configuration failed"/> <int value="2" label="Catchup configuration retried after browser restart"/> @@ -4843,7 +4843,7 @@ <int value="4" label="RESET_LOCAL_SYNC_DATA received"/> </enum> -<enum name="ClearSiteDataParameters" type="int"> +<enum name="ClearSiteDataParameters"> <int value="0" label="No datatypes"/> <int value="1" label="Cookies"/> <int value="2" label="Storage"/> @@ -4854,7 +4854,7 @@ <int value="7" label="Cookies, Storage, and Cache"/> </enum> -<enum name="ClientAppId" type="int"> +<enum name="ClientAppId"> <int value="0" label="Other"/> <int value="1" label="Gmail"/> <int value="2" label="Facebook"/> @@ -4869,13 +4869,13 @@ <int value="11" label="Gsa"/> </enum> -<enum name="ClipboardAction" type="int"> +<enum name="ClipboardAction"> <int value="0" label="Write from non-Incognito"/> <int value="1" label="Write from Incognito"/> <int value="2" label="Read Text"/> </enum> -<enum name="ClockStates" type="int"> +<enum name="ClockStates"> <int value="0" label="CLOCK_STATE_UNKNOWN: accuracy of system clock is unknown"/> <int value="1" label="CLOCK_STATE_OK: system clock is roughly accurate"/> @@ -4883,11 +4883,11 @@ <int value="3" label="CLOCK_STATE_FUTURE: system clock is in the future"/> </enum> -<enum name="CloudImportUserAction" type="int"> +<enum name="CloudImportUserAction"> <int value="0" label="IMPORT_INITIATED"/> </enum> -<enum name="CloudPrintAuthEventType" type="int"> +<enum name="CloudPrintAuthEventType"> <int value="0" label="AUTH_EVENT_ROBO_CREATE"/> <int value="1" label="AUTH_EVENT_ROBO_SUCCEEDED"/> <int value="2" label="AUTH_EVENT_ROBO_FAILED"/> @@ -4902,7 +4902,7 @@ <int value="11" label="AUTH_EVENT_NET_ERROR"/> </enum> -<enum name="CloudPrintJobHandlerEventType" type="int"> +<enum name="CloudPrintJobHandlerEventType"> <int value="0" label="JOB_HANDLER_CHECK_FOR_JOBS"/> <int value="1" label="JOB_HANDLER_START"/> <int value="2" label="JOB_HANDLER_PENDING_TASK"/> @@ -4920,21 +4920,21 @@ <int value="14" label="JOB_HANDLER_INVALID_DATA"/> </enum> -<enum name="CloudPrintJobStatusType" type="int"> +<enum name="CloudPrintJobStatusType"> <int value="0" label="JOB_SUCCESS"/> <int value="1" label="JOB_DOWNLOAD_FAILED"/> <int value="2" label="JOB_VALIDATE_TICKET_FAILED"/> <int value="3" label="JOB_FAILED"/> </enum> -<enum name="CloudPrintNativeJobStatusType" type="int"> +<enum name="CloudPrintNativeJobStatusType"> <int value="0" label="PRINT_JOB_STATUS_INVALID"/> <int value="1" label="PRINT_JOB_STATUS_IN_PROGRESS"/> <int value="2" label="PRINT_JOB_STATUS_ERROR"/> <int value="3" label="PRINT_JOB_STATUS_COMPLETED"/> </enum> -<enum name="CloudPrintUrlFetcherRequestType" type="int"> +<enum name="CloudPrintUrlFetcherRequestType"> <int value="0" label="REQUEST_AUTH_CODE"/> <int value="1" label="REQUEST_REGISTER"/> <int value="2" label="REQUEST_UNREGISTER"/> @@ -4946,33 +4946,33 @@ <int value="8" label="REQUEST_JOB_FETCH"/> </enum> -<enum name="CoalescePotentialPackets" type="int"> +<enum name="CoalescePotentialPackets"> <int value="0" label="No Advantage"/> <int value="1" label="Header packets Only"/> <int value="30" label="More Than 30"/> </enum> -<enum name="ColorSpaceExtractedRawDataResult" type="int"> +<enum name="ColorSpaceExtractedRawDataResult"> <int value="0" label="Failed to extract."/> <int value="1" label="Successfully extracted."/> </enum> -<enum name="ColorSpaceMatrixResult" type="int"> +<enum name="ColorSpaceMatrixResult"> <int value="0" label="Failed to extract toXYZD50 matrix."/> <int value="1" label="Successfully extracted toXYZD50 matrix."/> </enum> -<enum name="ColorSpaceNonlinearFitConverged" type="int"> +<enum name="ColorSpaceNonlinearFitConverged"> <int value="0" label="Did not converge."/> <int value="1" label="Converged."/> </enum> -<enum name="ColorSpaceNumericalResult" type="int"> +<enum name="ColorSpaceNumericalResult"> <int value="0" label="Failed to extract."/> <int value="1" label="Successfully extracted."/> </enum> -<enum name="CombinedHttpResponseAndNetErrorCode" type="int"> +<enum name="CombinedHttpResponseAndNetErrorCode"> <!-- Generated from net/base/net_error_list.h --> <int value="-806" label="DNS_SORT_ERROR"/> @@ -5235,7 +5235,7 @@ <int value="505" label="505: HTTP Version Not Supported"/> </enum> -<enum name="CommittedLoadEvent" type="int"> +<enum name="CommittedLoadEvent"> <obsolete> Deprecated in favor of PageLoad.Timing2.NavigationToCommit and PageLoad.AbortTiming. @@ -5245,30 +5245,30 @@ <int value="2" label="Successful first layout"/> </enum> -<enum name="ComponentUpdaterCalls" type="int"> +<enum name="ComponentUpdaterCalls"> <int value="0" label="Install"/> <int value="1" label="Update"/> </enum> -<enum name="CompositedScrolling" type="int"> +<enum name="CompositedScrolling"> <int value="0" label="Is scrollable area"/> <int value="1" label="Needs to be stacking container"/> <int value="2" label="Will use composited scrolling"/> </enum> -<enum name="CompositorScrollResult" type="int"> +<enum name="CompositorScrollResult"> <int value="0" label="ScrollOnMainThread"/> <int value="1" label="ScrollStarted"/> <int value="2" label="ScrollIgnored"/> <int value="3" label="ScrollUnknown"/> </enum> -<enum name="CompositorType" type="int"> +<enum name="CompositorType"> <int value="0" label="Software compositor"/> <int value="1" label="GPU compositor"/> </enum> -<enum name="CompressibleStringCountType" type="int"> +<enum name="CompressibleStringCountType"> <obsolete> Dprecated as of Aug 2016. CompressibleString has been reverted once at https://crrev.com/2227933002. @@ -5277,7 +5277,7 @@ <int value="1" label="Decompressed in a background or a foreground tab"/> </enum> -<enum name="ComputeCurrentSigninStatus" type="int"> +<enum name="ComputeCurrentSigninStatus"> <obsolete> Deprecated as of Jun 2016. The enum was added for debugging purpose and is not needed anymore. @@ -5290,7 +5290,7 @@ <int value="5" label="Try to override the status when its valus is error."/> </enum> -<enum name="ConfigParsingEvent" type="int"> +<enum name="ConfigParsingEvent"> <int value="0" label="SUCCESS"/> <int value="1" label="FAILURE"/> <int value="2" label="FAILURE_NO_FIELD_TRIAL"/> @@ -5304,7 +5304,7 @@ <int value="10" label="FAILURE_UNKNOWN_KEY"/> </enum> -<enum name="ConnectionDiagnosticsIssue" type="int"> +<enum name="ConnectionDiagnosticsIssue"> <int value="0" label="IP collision detected."/> <int value="1" label="Routing problem detected."/> <int value="2" label="HTTP issues or broken portal."/> @@ -5336,7 +5336,7 @@ <int value="22" label="Placeholder 4."/> </enum> -<enum name="ConnectionFailureReason" type="int"> +<enum name="ConnectionFailureReason"> <int value="0" label="Unknown"/> <int value="1" label="Bad Passphrase"/> <int value="2" label="Bad WEP Key"/> @@ -5350,7 +5350,7 @@ <int value="10" label="Pin Missing"/> </enum> -<enum name="ConnectionInfo" type="int"> +<enum name="ConnectionInfo"> <summary> Application protocol used for HTTP response as defined in net::HttpResponseInfo::ConnectionInfo. @@ -5374,19 +5374,19 @@ <int value="16" label="QUIC/38"/> </enum> -<enum name="ConnectionResult" type="int"> +<enum name="ConnectionResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Aborted"/> </enum> -<enum name="ConnectionStatus" type="int"> +<enum name="ConnectionStatus"> <int value="0" label="Offline"/> <int value="1" label="Connected"/> <int value="2" label="Online"/> </enum> -<enum name="ConnectionSubtype" type="int"> +<enum name="ConnectionSubtype"> <int value="0" label="UNKNOWN"/> <int value="1" label="NONE"/> <int value="2" label="OTHER"/> @@ -5422,7 +5422,7 @@ <int value="32" label="WIFI_AD"/> </enum> -<enum name="ConnectionType" type="int"> +<enum name="ConnectionType"> <obsolete> Removed May 2016. </obsolete> @@ -5460,7 +5460,7 @@ <int value="13" label="TLS-1.2">An SSL connection that uses TLS 1.2</int> </enum> -<enum name="ConnectivityDiagnosticsTestVerdict" type="int"> +<enum name="ConnectivityDiagnosticsTestVerdict"> <int value="0" label="NO_PROBLEM"/> <int value="1" label="POTENTIAL_PROBLEM"/> <int value="2" label="PROBLEM"/> @@ -5468,7 +5468,7 @@ <int value="4" label="TEST_NOT_RUN"/> </enum> -<enum name="ContentResourceType" type="int"> +<enum name="ContentResourceType"> <obsolete> Superseded by ContentResourceType in December 2015 when SUB_RESOURCE was split into RESOURCE_TYPE_SUB_RESOURCE and RESOURCE_TYPE_PLUGIN_RESOURCE, and @@ -5492,7 +5492,7 @@ <int value="15" label="RESOURCE_TYPE_SERVICE_WORKER"/> </enum> -<enum name="ContentResourceType2" type="int"> +<enum name="ContentResourceType2"> <int value="0" label="RESOURCE_TYPE_MAIN_FRAME"/> <int value="1" label="RESOURCE_TYPE_SUB_FRAME"/> <int value="2" label="RESOURCE_TYPE_STYLESHEET"/> @@ -5513,7 +5513,7 @@ <int value="17" label="RESOURCE_TYPE_PLUGIN_RESOURCE"/> </enum> -<enum name="ContentSetting" type="int"> +<enum name="ContentSetting"> <int value="0" label="DEFAULT"/> <int value="1" label="ALLOW"/> <int value="2" label="BLOCK"/> @@ -5522,14 +5522,14 @@ <int value="5" label="DETECT_IMPORTANT_CONTENT"/> </enum> -<enum name="ContentSettingMixedScriptAction" type="int"> +<enum name="ContentSettingMixedScriptAction"> <int value="0" label="Displayed shield"/> <int value="1" label="Displayed bubble"/> <int value="2" label="Clicked 'Load unsafe scripts'"/> <int value="3" label="Clicked 'Learn more'"/> </enum> -<enum name="ContentSettingPluginsAction" type="int"> +<enum name="ContentSettingPluginsAction"> <int value="0" label="Total number of navigations"/> <int value="1" label="Displayed plugin-blocked icon in Omnibox"/> <int value="2" label="Displayed bubble"/> @@ -5539,7 +5539,7 @@ <int value="6" label="Clicked 'Learn more'"/> </enum> -<enum name="ContentSettingPopupAction" type="int"> +<enum name="ContentSettingPopupAction"> <int value="0" label="Displayed popup-blocked icon in Omnibox"/> <int value="1" label="Displayed bubble"/> <int value="2" label="Clicked 'Always allow pop-ups from'"/> @@ -5549,7 +5549,7 @@ <int value="6" label="Clicked 'Always show on mobile'"/> </enum> -<enum name="ContentSettingScheme" type="int"> +<enum name="ContentSettingScheme"> <int value="0" label="(wildcard)"/> <int value="1" label="(other)"/> <int value="2" label="http"/> @@ -5558,7 +5558,7 @@ <int value="5" label="chrome-extension"/> </enum> -<enum name="ContentSuggestionsCategory" type="int"> +<enum name="ContentSuggestionsCategory"> <int value="0" label="Experimental"/> <int value="1" label="Recent Tabs"/> <int value="2" label="Downloads"/> @@ -5568,7 +5568,7 @@ <int value="6" label="Articles"/> </enum> -<enum name="ContentSuggestionsNotificationsAction" type="int"> +<enum name="ContentSuggestionsNotificationsAction"> <int value="0" label="Tap"/> <int value="1" label="Dismissal"/> <int value="2" label="Hidden (Notification deadline passed)"/> @@ -5579,17 +5579,17 @@ <int value="7" label="Settings"/> </enum> -<enum name="ContentSuggestionsNotificationsImpression" type="int"> +<enum name="ContentSuggestionsNotificationsImpression"> <int value="0" label="Article"/> <int value="1" label="Non-Article"/> </enum> -<enum name="ContentSuggestionsNotificationsOptOut" type="int"> +<enum name="ContentSuggestionsNotificationsOptOut"> <int value="0" label="Implicit"/> <int value="1" label="Explicit"/> </enum> -<enum name="ContentSuggestionsUIUpdateResult" type="int"> +<enum name="ContentSuggestionsUIUpdateResult"> <obsolete> Superseded by ContentSuggestionsUIUpdateResult2 in January 2017. </obsolete> @@ -5603,14 +5603,14 @@ <int value="7" label="Fail (updates disabled)"/> </enum> -<enum name="ContentSuggestionsUIUpdateResult2" type="int"> +<enum name="ContentSuggestionsUIUpdateResult2"> <int value="0" label="Success (appended)"/> <int value="1" label="Success (some suggestions replaced)"/> <int value="2" label="Fail (all suggestions seen)"/> <int value="3" label="Fail (updates disabled)"/> </enum> -<enum name="ContentType" type="int"> +<enum name="ContentType"> <int value="-1" label="Invalid setting"/> <int value="0" label="Cookies setting"/> <int value="1" label="Images setting"/> @@ -5648,7 +5648,7 @@ <int value="33" label="Ads metadata"/> </enum> -<enum name="ContentTypeParseableResult" type="int"> +<enum name="ContentTypeParseableResult"> <int value="0" label="IsSupported returned and MIME type parseable"/> <int value="1" label="MayBeSupported returned and MIME type parseable"/> <int value="2" label="IsNotSupported returned and MIME type parseable"/> @@ -5661,7 +5661,7 @@ label="IsNotSupported returned and MIME type not parseable (acceptable)"/> </enum> -<enum name="ContextLostReason" type="int"> +<enum name="ContextLostReason"> <summary>The reason for losing a GPU context.</summary> <int value="0" label="CONTEXT_INIT_FAILED"/> <int value="1" label="CONTEXT_LOST_GPU_CHANNEL_ERROR"/> @@ -5678,7 +5678,7 @@ <int value="12" label="CONTEXT_LOST_INVALID_GPU_MESSAGE"/> </enum> -<enum name="ContextMenuOption" type="int"> +<enum name="ContextMenuOption"> <summary>The item selected from a context menu</summary> <int value="0" label="Open in new tab"/> <int value="1" label="Open in incognito tab"/> @@ -5719,7 +5719,7 @@ <int value="36" label="Open in Chrome (Fullscreen)"/> </enum> -<enum name="ContextMenuSaveLinkType" type="int"> +<enum name="ContextMenuSaveLinkType"> <summary> The content type when user chooses save link context menu option </summary> @@ -5731,12 +5731,12 @@ <int value="5" label="Pdf"/> </enum> -<enum name="ContextProviderPhase" type="int"> +<enum name="ContextProviderPhase"> <int value="0" label="Acquired"/> <int value="1" label="Released"/> </enum> -<enum name="ContextualSearchBarOverlapSeen" type="int"> +<enum name="ContextualSearchBarOverlapSeen"> <int value="0" label="Overlap seen from Tap"/> <int value="1" label="Overlap not seen from Tap"/> <int value="2" label="No overlap seen from Tap"/> @@ -5747,12 +5747,12 @@ <int value="7" label="No overlap not seen from Longpress"/> </enum> -<enum name="ContextualSearchBasePageProtocol" type="int"> +<enum name="ContextualSearchBasePageProtocol"> <int value="0" label="Is HTTP"/> <int value="1" label="Not HTTP"/> </enum> -<enum name="ContextualSearchBlacklistSeen" type="int"> +<enum name="ContextualSearchBlacklistSeen"> <obsolete> Deprecated as of 5/2017. Experiment is finished. </obsolete> @@ -5770,7 +5770,7 @@ <int value="11" label="Misc, Not Seen"/> </enum> -<enum name="ContextualSearchEnterClosedStateChange" type="int"> +<enum name="ContextualSearchEnterClosedStateChange"> <int value="0" label="From Other"/> <int value="1" label="From Peeked (back press)"/> <int value="2" label="From Peeked (base page scroll)"/> @@ -5784,7 +5784,7 @@ <int value="10" label="From Maximized (SERP navigation)"/> </enum> -<enum name="ContextualSearchEnterExpandedStateChange" type="int"> +<enum name="ContextualSearchEnterExpandedStateChange"> <int value="0" label="From Other"/> <int value="1" label="From Peeked (search bar tap)"/> <int value="2" label="From Peeked (swipe)"/> @@ -5793,7 +5793,7 @@ <int value="5" label="From Maximized (fling)"/> </enum> -<enum name="ContextualSearchEnterMaximizedStateChange" type="int"> +<enum name="ContextualSearchEnterMaximizedStateChange"> <int value="0" label="Other"/> <int value="1" label="From Peeked (swipe)"/> <int value="2" label="From Peeked (fling)"/> @@ -5802,7 +5802,7 @@ <int value="5" label="From Expanded (SERP navigation)"/> </enum> -<enum name="ContextualSearchEnterPeekedStateChange" type="int"> +<enum name="ContextualSearchEnterPeekedStateChange"> <int value="0" label="From Other"/> <int value="1" label="From Closed (text select tap)"/> <int value="2" label="From Closed (text select long press)"/> @@ -5815,13 +5815,13 @@ <int value="9" label="From Maximized (fling)"/> </enum> -<enum name="ContextualSearchExitClosedStateChange" type="int"> +<enum name="ContextualSearchExitClosedStateChange"> <int value="0" label="Other"/> <int value="1" label="Peek (text select tap)"/> <int value="2" label="Peek (text select long press)"/> </enum> -<enum name="ContextualSearchExitExpandedStateChange" type="int"> +<enum name="ContextualSearchExitExpandedStateChange"> <int value="0" label="Other"/> <int value="1" label="Close (back press)"/> <int value="2" label="Close (base page tap)"/> @@ -5834,7 +5834,7 @@ <int value="9" label="Maximize (SERP navigation)"/> </enum> -<enum name="ContextualSearchExitMaximizedStateChange" type="int"> +<enum name="ContextualSearchExitMaximizedStateChange"> <int value="0" label="Other"/> <int value="1" label="Close (back press)"/> <int value="2" label="Close (fling)"/> @@ -5846,7 +5846,7 @@ <int value="8" label="Expand (fling)"/> </enum> -<enum name="ContextualSearchExitPeekedStateChange" type="int"> +<enum name="ContextualSearchExitPeekedStateChange"> <int value="0" label="Other"/> <int value="1" label="Close (back press)"/> <int value="2" label="Close (base page scroll)"/> @@ -5860,12 +5860,12 @@ <int value="10" label="To Maximize (fling)"/> </enum> -<enum name="ContextualSearchFirstRunPanelSeen" type="int"> +<enum name="ContextualSearchFirstRunPanelSeen"> <int value="0" label="Seen"/> <int value="1" label="Unseen"/> </enum> -<enum name="ContextualSearchIconSpriteAnimated" type="int"> +<enum name="ContextualSearchIconSpriteAnimated"> <int value="0" label="Animated, seen, from tap"/> <int value="1" label="Animated, not seen, from tap"/> <int value="2" label="Not animated, seen, from tap"/> @@ -5876,12 +5876,12 @@ <int value="7" label="Not animated, not seen, from long press"/> </enum> -<enum name="ContextualSearchLoaded" type="int"> +<enum name="ContextualSearchLoaded"> <int value="0" label="Partially Loaded"/> <int value="1" label="Fully Loaded"/> </enum> -<enum name="ContextualSearchOutcomeByGesture" type="int"> +<enum name="ContextualSearchOutcomeByGesture"> <int value="0" label="Enabled, from Tap"/> <int value="1" label="Disabled, from Tap"/> <int value="2" label="Undecided from Tap"/> @@ -5890,7 +5890,7 @@ <int value="5" label="Undecided from Long-press"/> </enum> -<enum name="ContextualSearchPeekPromoOutcome" type="int"> +<enum name="ContextualSearchPeekPromoOutcome"> <summary>The outcome of the Contextual Search Peek Promo.</summary> <int value="0" label="Peek Promo was seen, Panel was opened"/> <int value="1" label="Peek Promo was seen, Panel was not opened"/> @@ -5898,19 +5898,19 @@ <int value="3" label="Peek Promo was not seen, Panel was not opened"/> </enum> -<enum name="ContextualSearchPreferenceState" type="int"> +<enum name="ContextualSearchPreferenceState"> <int value="0" label="Uninitialized"/> <int value="1" label="Enabled"/> <int value="2" label="Disabled"/> </enum> -<enum name="ContextualSearchPrefetchSummary" type="int"> +<enum name="ContextualSearchPrefetchSummary"> <int value="0" label="Prefetched, partly loaded"/> <int value="1" label="Fully preloaded"/> <int value="2" label="Not prefetched"/> </enum> -<enum name="ContextualSearchQuickActionCategory" type="int"> +<enum name="ContextualSearchQuickActionCategory"> <int value="0" label="None"/> <int value="1" label="Address"/> <int value="2" label="Email"/> @@ -5919,13 +5919,13 @@ <int value="5" label="Website"/> </enum> -<enum name="ContextualSearchQuickActionIntentResolution" type="int"> +<enum name="ContextualSearchQuickActionIntentResolution"> <int value="0" label="No matching apps or resolve failed"/> <int value="1" label="One matching app"/> <int value="2" label="Multiple matching apps"/> </enum> -<enum name="ContextualSearchQuickAnswerSeen" type="int"> +<enum name="ContextualSearchQuickAnswerSeen"> <int value="0" label="Activated, answered and seen"/> <int value="1" label="Activated and answered but not seen"/> <int value="2" label="Activated, not answered but seen"/> @@ -5934,34 +5934,34 @@ <int value="5" label="Not activated nor seen"/> </enum> -<enum name="ContextualSearchResolvedTermWords" type="int"> +<enum name="ContextualSearchResolvedTermWords"> <int value="0" label="Single Word"/> <int value="1" label="Multi Word"/> </enum> -<enum name="ContextualSearchResultsSeen" type="int"> +<enum name="ContextualSearchResultsSeen"> <int value="0" label="Seen"/> <int value="1" label="Unseen"/> </enum> -<enum name="ContextualSearchSearchRequestStatus" type="int"> +<enum name="ContextualSearchSearchRequestStatus"> <int value="0" label="Not Failed"/> <int value="1" label="Failed"/> </enum> -<enum name="ContextualSearchSeenByGesture" type="int"> +<enum name="ContextualSearchSeenByGesture"> <int value="0" label="Seen, from Tap"/> <int value="1" label="Not seen, from Tap"/> <int value="2" label="Seen, from Long-press"/> <int value="3" label="Not seen, from Long-press"/> </enum> -<enum name="ContextualSearchSelectionValid" type="int"> +<enum name="ContextualSearchSelectionValid"> <int value="0" label="Valid"/> <int value="1" label="Invalid"/> </enum> -<enum name="ContextualSearchShouldTranslate" type="int"> +<enum name="ContextualSearchShouldTranslate"> <summary> Notes when a translation one-box should be forced by Contextual Search. </summary> @@ -5969,19 +5969,19 @@ <int value="1" label="Would force a translation (if not disabled)"/> </enum> -<enum name="ContextualSearchSuppressionResultsSeen" type="int"> +<enum name="ContextualSearchSuppressionResultsSeen"> <int value="0" label="Seen, heuristic satisfied"/> <int value="1" label="Not seen, heuristic satisfied"/> <int value="2" label="Seen, heuristic not satisfied"/> <int value="3" label="Not seen, heuristic not satisfied"/> </enum> -<enum name="ContextualSearchTapSuppression" type="int"> +<enum name="ContextualSearchTapSuppression"> <int value="0" label="Tap suppressed"/> <int value="1" label="Tap not suppressed"/> </enum> -<enum name="CookieDeleteEquivalent" type="int"> +<enum name="CookieDeleteEquivalent"> <int value="0" label="Attempt to delete an equivalent cookie during a set cookie operation"/> @@ -5993,7 +5993,7 @@ rules would have been deleted in non-strict secure cookie case"/> </enum> -<enum name="CookieDeletionCause" type="int"> +<enum name="CookieDeletionCause"> <summary>Reason why a cookie was removed from the cookie store</summary> <int value="0" label="explicit"> The user explicitly requested that we delete a cookie @@ -6037,27 +6037,27 @@ </int> </enum> -<enum name="CookieOrCacheDeletion" type="int"> +<enum name="CookieOrCacheDeletion"> <int value="0" label="Neither"/> <int value="1" label="Only cookies"/> <int value="2" label="Only cache"/> <int value="3" label="Both"/> </enum> -<enum name="CookiePrefix" type="int"> +<enum name="CookiePrefix"> <int value="0" label="No special prefix"/> <int value="1" label="Secure prefix"/> <int value="2" label="Host prefix"/> </enum> -<enum name="CookieSourceScheme" type="int"> +<enum name="CookieSourceScheme"> <int value="0" label="Secure cookie, source scheme is cryptographic"/> <int value="1" label="Secure cookie, source scheme is not cryptographic"/> <int value="2" label="Not Secure cookie, source scheme is cryptographic"/> <int value="3" label="Not Secure cookie, source scheme is not cryptographic"/> </enum> -<enum name="CookieType" type="int"> +<enum name="CookieType"> <summary>The type of a cookie when its added to the cookie store.</summary> <int value="0" label="Default"/> <int value="1" label="First-Party-Only"/> @@ -6069,13 +6069,13 @@ <int value="7" label="First-Party-Only, HttpOnly, Secure"/> </enum> -<enum name="CopylessCacheHit" type="int"> +<enum name="CopylessCacheHit"> <int value="0" label="Cache hit with entity"/> <int value="1" label="Cache hit without entity"/> <int value="2" label="Cache miss"/> </enum> -<enum name="CorePageTransition" type="int"> +<enum name="CorePageTransition"> <summary> The core value of PageTransition. See ui/base/page_transition_types.h. </summary> @@ -6092,7 +6092,7 @@ <int value="10" label="KEYWORD_GENERATED"/> </enum> -<enum name="CorruptExtensionDisabledReason" type="int"> +<enum name="CorruptExtensionDisabledReason"> <summary> The reason why content verification flagged an extension as corrupted. See ContentVerifyJob::FailureReason in @@ -6104,7 +6104,7 @@ <int value="3" label="Hash Mismatch"/> </enum> -<enum name="CrashExitCodes" type="int"> +<enum name="CrashExitCodes"> <int value="1" label="RESULT_CODE_KILLED"/> <int value="2" label="RESULT_CODE_HUNG"/> <int value="3" label="RESULT_CODE_KILLED_BAD_MESSAGE"/> @@ -6185,7 +6185,7 @@ <int value="2147483646" label="STATUS_DATATYPE_MISALIGNMENT"/> </enum> -<enum name="CrashpadExceptionCaptureResult" type="int"> +<enum name="CrashpadExceptionCaptureResult"> <int value="0" label="kSuccess"/> <int value="1" label="kUnexpectedExceptionBehavior"/> <int value="2" label="kFailedDueToSuspendSelf"/> @@ -6196,12 +6196,12 @@ <int value="7" label="kFinishWritingCrashReportFailed"/> </enum> -<enum name="CrashpadExceptionProcessingState" type="int"> +<enum name="CrashpadExceptionProcessingState"> <int value="0" label="kStarted"/> <int value="1" label="kFinished"/> </enum> -<enum name="CrashpadLifetimeMilestone" type="int"> +<enum name="CrashpadLifetimeMilestone"> <int value="0" label="kStarted"/> <int value="1" label="kExitedNormally"/> <int value="2" label="kExitedEarly"/> @@ -6210,7 +6210,7 @@ <int value="5" label="kCrashed"/> </enum> -<enum name="CrashpadMacExceptionCodes" type="int"> +<enum name="CrashpadMacExceptionCodes"> <int value="1" label="EXC_BAD_ACCESS"/> <int value="2" label="EXC_BAD_INSTRUCTION"/> <int value="3" label="EXC_ARITHMETIC"/> @@ -6316,17 +6316,17 @@ <int value="1396902912" label="SIGSYS/0"/> </enum> -<enum name="CrashpadReportPending" type="int"> +<enum name="CrashpadReportPending"> <int value="0" label="kNewlyCreated"/> <int value="1" label="kUserInitiated"/> </enum> -<enum name="CrashpadUploadAttemptStatus" type="int"> +<enum name="CrashpadUploadAttemptStatus"> <int value="0" label="Failed"/> <int value="1" label="Succeeded"/> </enum> -<enum name="CrashpadUploadSkippedReason" type="int"> +<enum name="CrashpadUploadSkippedReason"> <int value="0" label="kUploadsDisabled"/> <int value="1" label="kUploadThrottled"/> <int value="2" label="kUnexpectedTime"/> @@ -6334,7 +6334,7 @@ <int value="4" label="kUploadFailed"/> </enum> -<enum name="CrashpadWinExceptionCodes" type="int"> +<enum name="CrashpadWinExceptionCodes"> <int value="-2147483647" label="EXCEPTION_GUARD_PAGE"/> <int value="-2147483646" label="EXCEPTION_DATATYPE_MISALIGNMENT"/> <int value="-2147483645" label="EXCEPTION_BREAKPOINT"/> @@ -6402,7 +6402,7 @@ <int value="250477278" label="(Delphi exception)"/> </enum> -<enum name="CreatePersistentHistogramResult" type="int"> +<enum name="CreatePersistentHistogramResult"> <int value="0" label="Success: Histogram created in persistent space."/> <int value="1" label="Error: Invalid metadata pointer. (coding error)"/> <int value="2" label="Error: Invalid metdata."/> @@ -6415,12 +6415,12 @@ <int value="9" label="Error: Allocator has become corrupted."/> </enum> -<enum name="CredentialFilteredType" type="int"> +<enum name="CredentialFilteredType"> <int value="0" label="No sync credentials present"/> <int value="1" label="Sync credentials were removed"/> </enum> -<enum name="CredentialManagerGetResult" type="int"> +<enum name="CredentialManagerGetResult"> <int value="0" label="Promise rejected"/> <int value="1" label="Empty credential, auto sign-in disallowed"/> <int value="2" label="Empty credential, empty password store"/> @@ -6432,14 +6432,14 @@ <int value="8" label="Auto sign-in"/> </enum> -<enum name="CrosBeamformingDeviceState" type="int"> +<enum name="CrosBeamformingDeviceState"> <int value="0" label="Default enabled"/> <int value="1" label="User enabled"/> <int value="2" label="Default disabled"/> <int value="3" label="User disabled"/> </enum> -<enum name="CrosDisksArchiveType" type="int"> +<enum name="CrosDisksArchiveType"> <int value="0" label="Unknown"/> <int value="1" label="ZIP"/> <int value="2" label="RAR"/> @@ -6448,7 +6448,7 @@ <int value="5" label="Gzip-compressed Tar"/> </enum> -<enum name="CrosDisksDeviceMediaType" type="int"> +<enum name="CrosDisksDeviceMediaType"> <int value="0" label="Unknown"/> <int value="1" label="USB Drive"/> <int value="2" label="SD Card"/> @@ -6457,7 +6457,7 @@ <int value="5" label="DVD"/> </enum> -<enum name="CrosDisksFilesystemType" type="int"> +<enum name="CrosDisksFilesystemType"> <int value="0" label="Unknown"/> <int value="1" label="Others"/> <int value="2" label="FAT"/> @@ -6471,7 +6471,7 @@ <int value="10" label="UDF"/> </enum> -<enum name="CrosEnableDriveOfflineOutcome" type="int"> +<enum name="CrosEnableDriveOfflineOutcome"> <int value="0" label="Success: Offline mode enabled"/> <int value="1" label="Failure: Hosted app page timed out"/> <int value="2" label="Failure: Hosted app page load failed"/> @@ -6480,7 +6480,7 @@ <int value="5" label="Failure: Background page already exists"/> </enum> -<enum name="CrosEventEnum" type="int"> +<enum name="CrosEventEnum"> <int value="0" label="ModemManagerCommandSendFailure"/> <int value="1" label="HwWatchdogReboot"/> <int value="2" label="Cras.NoCodecsFoundAtBoot"/> @@ -6504,13 +6504,13 @@ <int value="20" label="Watchdog.StartupFailed"/> </enum> -<enum name="CrosFirstRunTutorialCompletionType" type="int"> +<enum name="CrosFirstRunTutorialCompletionType"> <int value="0" label="Was not finished"/> <int value="1" label="Finished with "Got It" button"/> <int value="2" label="Finished with "Keep Exploring" button"/> </enum> -<enum name="CrosShelfClickTarget" type="int"> +<enum name="CrosShelfClickTarget"> <obsolete> Deprecated as of 12/2013. Default pinned apps trial is finished. </obsolete> @@ -6525,14 +6525,14 @@ <int value="8" label="PlayMusic"/> </enum> -<enum name="CrossOriginAutoplayResult" type="int"> +<enum name="CrossOriginAutoplayResult"> <int value="0" label="Allowed"/> <int value="1" label="Blocked"/> <int value="2" label="PlayedWithGesture"/> <int value="3" label="UserPaused"/> </enum> -<enum name="CrosTPMDictionaryAttackResetStatusEnum" type="int"> +<enum name="CrosTPMDictionaryAttackResetStatusEnum"> <int value="0" label="Reset not necessary"/> <int value="1" label="Reset attempt succeeded"/> <int value="2" label="Reset attempt failed"/> @@ -6541,7 +6541,7 @@ <int value="5" label="Failed to query dictionary attack counter"/> </enum> -<enum name="CryptohomeChecksumStatus" type="int"> +<enum name="CryptohomeChecksumStatus"> <int value="0" label="Checksum OK"/> <int value="1" label="Checksum does not exist"/> <int value="2" label="Checksum read error"/> @@ -6549,7 +6549,7 @@ <int value="4" label="Checksum out of sync"/> </enum> -<enum name="CryptohomeError" type="int"> +<enum name="CryptohomeError"> <int value="1" label="TPM returned TPM_E_FAIL"/> <int value="2" label="TCS key load failed"/> <int value="3" label="TPM dictionary defense lock is running"/> @@ -6571,14 +6571,14 @@ <int value="18" label="Keyset wrapped both by TPM and Scrypt"/> </enum> -<enum name="CryptohomeMigrationToGaiaId" type="int"> +<enum name="CryptohomeMigrationToGaiaId"> <int value="0" label="Not started"/> <int value="1" label="Already migrated"/> <int value="2" label="Success"/> <int value="3" label="Failure"/> </enum> -<enum name="CryptohomeTpmResults" type="int"> +<enum name="CryptohomeTpmResults"> <int value="1" label="TPM Success"/> <int value="2" label="TPM Error Authentication Fail"/> <int value="3" label="TPM Error Bad Parameter"/> @@ -6775,13 +6775,13 @@ <int value="194" label="TSS Error Unknown Error"/> </enum> -<enum name="CTLogEntryInclusionCheckResult" type="int"> +<enum name="CTLogEntryInclusionCheckResult"> <int value="0" label="Obtained valid inclusion proof"/> <int value="1" label="Failed getting inclusion proof"/> <int value="2" label="Obtained inclusion proof is invalid"/> </enum> -<enum name="CTRequirementCompliance" type="int"> +<enum name="CTRequirementCompliance"> <obsolete> Deprecated 1/2016. </obsolete> @@ -6790,7 +6790,7 @@ <int value="2" label="Has enough SCTs"/> </enum> -<enum name="CustomTabsSpeculationStatusOnStart" type="int"> +<enum name="CustomTabsSpeculationStatusOnStart"> <int value="0" label="Speculation allowed. If started, the kind will also be recorded"/> <int value="1" label="Prefetch kind of speculation started"/> @@ -6804,14 +6804,14 @@ <int value="9" label="Not allowed: Network metered"/> </enum> -<enum name="CustomTabsSpeculationStatusOnSwap" type="int"> +<enum name="CustomTabsSpeculationStatusOnSwap"> <int value="0" label="Background Tab Swapped In"/> <int value="1" label="Background Tab Not Matched"/> <int value="2" label="Prerender Swapped In"/> <int value="3" label="Prerender Not Matched"/> </enum> -<enum name="D3D11FeatureLevel" type="int"> +<enum name="D3D11FeatureLevel"> <int value="0" label="Unknown"/> <int value="1" label="No D3D11 DLL"/> <int value="2" label="No D3D11CreateDevice entry point"/> @@ -6824,7 +6824,7 @@ <int value="9" label="11.0"/> </enum> -<enum name="D3D11InitializeResult" type="int"> +<enum name="D3D11InitializeResult"> <int value="0" label="Success"/> <int value="1" label="Error initializing compiler"/> <int value="2" label="Missing DLL dependency"/> @@ -6845,7 +6845,7 @@ <int value="14" label="D3D11CreateDevice returned DXGI_ERROR_DEVICE_HUNG"/> </enum> -<enum name="D3D9InitializeResult" type="int"> +<enum name="D3D9InitializeResult"> <int value="0" label="Success"/> <int value="1" label="Error initializing compiler"/> <int value="2" label="Missing DLL dependency"/> @@ -6856,7 +6856,7 @@ <int value="7" label="Other initialization error"/> </enum> -<enum name="D3DFeatureLevel" type="int"> +<enum name="D3DFeatureLevel"> <int value="0" label="D3D_FEATURE_LEVEL_INVALID"/> <int value="1" label="D3D_FEATURE_LEVEL_9_3"/> <int value="2" label="D3D_FEATURE_LEVEL_10_0"/> @@ -6865,36 +6865,36 @@ <int value="5" label="D3D_FEATURE_LEVEL_11_1"/> </enum> -<enum name="DailyEventIntervalType" type="int"> +<enum name="DailyEventIntervalType"> <int value="0" label="First Run"/> <int value="1" label="Day Elapsed"/> <int value="2" label="Clock Changed"/> </enum> -<enum name="DangerousFile.Reason" type="int"> +<enum name="DangerousFile.Reason"> <int value="0" label="Safe Browsing is not available"/> <int value="1" label="Safe Browsing returns UNKOWN"/> <int value="2" label="Safe Browsing returns SAFE"/> </enum> -<enum name="DarkResumeScanRetryResult" type="int"> +<enum name="DarkResumeScanRetryResult"> <int value="0" label="Not Connected"/> <int value="1" label="Connected"/> </enum> -<enum name="DarkResumeUnmatchedScanResultReceived" type="int"> +<enum name="DarkResumeUnmatchedScanResultReceived"> <int value="0" label="False (all scan results match)"/> <int value="1" label="True (at least one unmatched scan result)"/> </enum> -<enum name="DarkResumeWakeReason" type="int"> +<enum name="DarkResumeWakeReason"> <int value="0" label="Unsupported (or not reported)"/> <int value="1" label="Pattern"/> <int value="2" label="Disconnect"/> <int value="3" label="SSID"/> </enum> -<enum name="DataChannelCounters" type="int"> +<enum name="DataChannelCounters"> <int value="0" label="Channel created."/> <int value="1" label="Channel reached Open state."/> <int value="2" label="Channel is reliable."/> @@ -6902,7 +6902,7 @@ <int value="4" label="Channel is negotiated."/> </enum> -<enum name="DataReductionProxyAutoLoFiAccuracy" type="int"> +<enum name="DataReductionProxyAutoLoFiAccuracy"> <int value="0" label="Estimated network quality as slow and was actually slow"/> <int value="1" @@ -6913,14 +6913,14 @@ label="Estimated network quality as not slow and was actually not slow"/> </enum> -<enum name="DataReductionProxyAutoLoFiRequestHeaderState" type="int"> +<enum name="DataReductionProxyAutoLoFiRequestHeaderState"> <int value="0" label="Empty to Empty"/> <int value="1" label="Empty to Low"/> <int value="2" label="Low to Empty"/> <int value="3" label="Low to Low"/> </enum> -<enum name="DataReductionProxyBypassEventType_Deprecated" type="int"> +<enum name="DataReductionProxyBypassEventType_Deprecated"> <int value="0" label="Short bypass"/> <int value="1" label="Long bypass"/> <int value="2" label="Bypass due to internal server error"/> @@ -6931,7 +6931,7 @@ label="Bypass due to 407 response from proxy without a challenge"/> </enum> -<enum name="DataReductionProxyBypassType" type="int"> +<enum name="DataReductionProxyBypassType"> <int value="0" label="Bypass due to explicit instruction for the current request"/> <int value="1" @@ -6951,29 +6951,29 @@ <int value="10" label="Bypass due to any network error"/> </enum> -<enum name="DataReductionProxyConfigServiceAuthExpiredSessionKey" type="int"> +<enum name="DataReductionProxyConfigServiceAuthExpiredSessionKey"> <int value="0" label="Current session key does not match the key in the request"/> <int value="1" label="Current session key matches the key in the request"/> </enum> -<enum name="DataReductionProxyConfigServiceHTTPRequests" type="int"> +<enum name="DataReductionProxyConfigServiceHTTPRequests"> <int value="0" label="Request did not go through data saver proxy"/> <int value="1" label="Request went through data saver proxy"/> </enum> -<enum name="DataReductionProxyEnabledState" type="int"> +<enum name="DataReductionProxyEnabledState"> <int value="0" label="Off-to-On"/> <int value="1" label="On-to-Off"/> </enum> -<enum name="DataReductionProxyLoFiImplicitOptOutAction" type="int"> +<enum name="DataReductionProxyLoFiImplicitOptOutAction"> <int value="0" label="Lo-Fi disabled for the remainder of the session"/> <int value="1" label="Lo-Fi disabled until next opt out epoch"/> <int value="2" label="Next implict opt out epoch, Lo-Fi re-enabled"/> </enum> -<enum name="DataReductionProxyLoFiSessionState" type="int"> +<enum name="DataReductionProxyLoFiSessionState"> <int value="0" label="Lo-Fi was used"/> <int value="1" label="Lo-Fi was not used because the network quality was always good"/> @@ -6985,14 +6985,14 @@ out"/> </enum> -<enum name="DataReductionProxyLoFiTransformationType" type="int"> +<enum name="DataReductionProxyLoFiTransformationType"> <int value="0" label="Pageloads that are lite pages"/> <int value="1" label="Pageloads that requested lite pages, but did not have the transformation"/> </enum> -<enum name="DataReductionProxyLoFiUIAction" type="int"> +<enum name="DataReductionProxyLoFiUIAction"> <int value="0" label="'Load images' snackbar shown"/> <int value="1" label="'Load images' snackbar clicked"/> <int value="2" label="'Load image' context menu item shown"/> @@ -7003,12 +7003,12 @@ <int value="6" label="'Load images' context menu item clicked"/> </enum> -<enum name="DataReductionProxyNetworkChangeEvent" type="int"> +<enum name="DataReductionProxyNetworkChangeEvent"> <int value="0" label="IP Address Change"/> <int value="1" label="Proxy disabled on VPN (deprecated)"/> </enum> -<enum name="DataReductionProxyProbeURLFetchResult" type="int"> +<enum name="DataReductionProxyProbeURLFetchResult"> <int value="0" label="Internet disconnected"/> <int value="1" label="Probe failed, proxy disabled"/> <int value="2" label="Probe failed, proxy already disabled"/> @@ -7017,14 +7017,14 @@ <int value="5" label="Probe started, proxy disabled"/> </enum> -<enum name="DataReductionProxyPromoAction" type="int"> +<enum name="DataReductionProxyPromoAction"> <int value="0" label="Dismissed from first screen"/> <int value="1" label="Dismissed from second screen"/> <int value="2" label="Enabled from first screen"/> <int value="3" label="Enabled from second screen"/> </enum> -<enum name="DataReductionProxyProxyPrefMigrationResult" type="int"> +<enum name="DataReductionProxyProxyPrefMigrationResult"> <int value="0" label="Proxy pref not cleared"/> <int value="1" label="Empty proxy pref was cleared"/> <int value="2" label="System proxy pref was cleared"/> @@ -7036,14 +7036,14 @@ *.googlezip.net proxy was cleared"/> </enum> -<enum name="DataReductionProxyProxySchemeUsed" type="int"> +<enum name="DataReductionProxyProxySchemeUsed"> <int value="0" label="Unknown"/> <int value="1" label="HTTP"/> <int value="2" label="HTTPS"/> <int value="3" label="QUIC"/> </enum> -<enum name="DataReductionProxyQuicDefaultAlternativeProxy" type="int"> +<enum name="DataReductionProxyQuicDefaultAlternativeProxy"> <obsolete> Deprecated in 5/2017, since the experiment to use default QUIC alternative proxy was deprecated. @@ -7055,39 +7055,39 @@ reduction proxies"/> </enum> -<enum name="DataReductionProxyQuicProxyStatus" type="int"> +<enum name="DataReductionProxyQuicProxyStatus"> <int value="0" label="QUIC proxy was available"/> <int value="1" label="Resolved HTTPS data reduction proxy does not support QUIC"/> <int value="2" label="QUIC proxies have been marked as broken"/> </enum> -<enum name="DataReductionProxyResourceContentType" type="int"> +<enum name="DataReductionProxyResourceContentType"> <int value="0" label="Unknown"/> <int value="1" label="Media"/> </enum> -<enum name="DataReductionProxyResponseProxyServerStatus" type="int"> +<enum name="DataReductionProxyResponseProxyServerStatus"> <int value="0" label="Empty proxy server"/> <int value="1" label="DRP proxy server"/> <int value="2" label="Non-DRP proxy server without DRP via header"/> <int value="3" label="Non-DRP proxy server with DRP via header"/> </enum> -<enum name="DataReductionProxySettingsConversion" type="int"> +<enum name="DataReductionProxySettingsConversion"> <int value="0" label="OFF to OFF"/> <int value="1" label="OFF to ON"/> <int value="2" label="ON to OFF"/> <int value="3" label="ON to ON"/> </enum> -<enum name="DataReductionProxyStartupState" type="int"> +<enum name="DataReductionProxyStartupState"> <int value="0" label="Proxy not available"/> <int value="1" label="Proxy available but not enabled"/> <int value="2" label="Proxy available and enabled"/> </enum> -<enum name="DataReductionProxyStoreStatus" type="int"> +<enum name="DataReductionProxyStoreStatus"> <int value="0" label="OK"/> <int value="1" label="NOT_FOUND"/> <int value="2" label="CORRUPTED"/> @@ -7095,7 +7095,7 @@ <int value="4" label="MISC_ERROR"/> </enum> -<enum name="DataReductionProxyUIAction" type="int"> +<enum name="DataReductionProxyUIAction"> <int value="0" label="Enabled directly from the Second Run promo"/> <int value="1" label="Enabled then disabled from promo (iOS-only)"/> <int value="2" @@ -7145,7 +7145,7 @@ <int value="26" label="Site breakdown expanded to see more sites"/> </enum> -<enum name="DataUrlMimeType" type="int"> +<enum name="DataUrlMimeType"> <int value="0" label="Other"/> <int value="1" label="HTML"/> <int value="2" label="XHTML"/> @@ -7153,21 +7153,21 @@ <int value="4" label="SVG"/> </enum> -<enum name="DataUsageReportSubmissionResult" type="int"> +<enum name="DataUsageReportSubmissionResult"> <int value="0" label="Successful"/> <int value="1" label="Failed"/> <int value="2" label="Timed out"/> <int value="3" label="Lost"/> </enum> -<enum name="DataUsageTrackingSessionEndReason" type="int"> +<enum name="DataUsageTrackingSessionEndReason"> <int value="0" label="Omnibox search navigation"/> <int value="1" label="Omnibox navigation"/> <int value="2" label="Bookmark navigation"/> <int value="3" label="History navigation"/> </enum> -<enum name="DataUsageTrackingSessionStartReason" type="int"> +<enum name="DataUsageTrackingSessionStartReason"> <int value="0" label="Package regex match in Custom Tab"/> <int value="1" label="Omnibox search navigation"/> <int value="2" label="Omnibox navigation"/> @@ -7176,7 +7176,7 @@ <int value="5" label="Page reload"/> </enum> -<enum name="DataUsageUIAction" type="int"> +<enum name="DataUsageUIAction"> <int value="0" label="Data use tracking started snackbar shown"/> <int value="1" label="Data use tracking started snackbar 'More' link clicked"/> @@ -7192,7 +7192,7 @@ <int value="8" label="Data use tracking ended dialog opted out"/> </enum> -<enum name="DataUseContentType" type="int"> +<enum name="DataUseContentType"> <int value="0" label="Other"/> <int value="1" label="Mainframe HTML"/> <int value="2" label="Non Mainframe HTML"/> @@ -7208,7 +7208,7 @@ <int value="12" label="Video - Tab in foreground"/> </enum> -<enum name="DataUsePageTransition" type="int"> +<enum name="DataUsePageTransition"> <summary>PageTransitions in ui/base/page_transition_types.h.</summary> <int value="0" label="LINK"/> <int value="1" label="TYPED"/> @@ -7223,7 +7223,7 @@ <int value="10" label="HOME_PAGE"/> </enum> -<enum name="DataUseServices" type="int"> +<enum name="DataUseServices"> <int value="0" label="Not Tagged"/> <int value="1" label="Suggestions"/> <int value="2" label="Translate"/> @@ -7267,7 +7267,7 @@ <int value="40" label="LargeIconService"/> </enum> -<enum name="DCLayerResult" type="int"> +<enum name="DCLayerResult"> <int value="0" label="Success"/> <int value="1" label="Failed unsupported quad"/> <int value="2" label="Failed quad blend mode"/> @@ -7276,7 +7276,7 @@ <int value="5" label="Failed complex transform"/> </enum> -<enum name="DeclarativeAPIFunctionType" type="int"> +<enum name="DeclarativeAPIFunctionType"> <int value="0" label="kDeclarativeContentAddRules"/> <int value="1" label="kDeclarativeContentRemoveRules"/> <int value="2" label="kDeclarativeContentGetRules"/> @@ -7288,7 +7288,7 @@ <int value="8" label="kDeclarativeWebRequestWebviewGetRules"/> </enum> -<enum name="DecodedImageOrientation" type="int"> +<enum name="DecodedImageOrientation"> <int value="0" label="Unknown"/> <int value="1" label="Top Left"/> <int value="2" label="Top Right"/> @@ -7300,7 +7300,7 @@ <int value="8" label="Left Bottom"/> </enum> -<enum name="DecodedImageType" type="int"> +<enum name="DecodedImageType"> <int value="0" label="kImageUnknown"/> <int value="1" label="kImageJPEG"/> <int value="2" label="kImagePNG"/> @@ -7310,7 +7310,7 @@ <int value="6" label="kImageBMP"/> </enum> -<enum name="DefaultBrowserAsyncAttemptResult" type="int"> +<enum name="DefaultBrowserAsyncAttemptResult"> <obsolete> Deprecated 2015/11. Renamed to SetDefaultAttemptResult. </obsolete> @@ -7338,7 +7338,7 @@ </int> </enum> -<enum name="DefaultBrowserInfoBarUserInteraction" type="int"> +<enum name="DefaultBrowserInfoBarUserInteraction"> <int value="0" label="Accept"> The user clicked the "Set as default" button. </int> @@ -7351,13 +7351,13 @@ <int value="3" label="Dismiss">The user explicitly closed the infobar.</int> </enum> -<enum name="DefaultBrowserState" type="int"> +<enum name="DefaultBrowserState"> <int value="0" label="Not Default"/> <int value="1" label="Default"/> <int value="2" label="Unknown"/> </enum> -<enum name="DefaultSearchChangeOrigin" type="int"> +<enum name="DefaultSearchChangeOrigin"> <int value="0" label="DSP changed by synced Pref"/> <int value="1" label="DSP changed by Sync ADD"/> <int value="2" label="DSP changed by Sync DELETE"/> @@ -7369,7 +7369,7 @@ <int value="8" label="DSP set to new engine with no previous value in prefs"/> </enum> -<enum name="DefaultTouchBarActions" type="int"> +<enum name="DefaultTouchBarActions"> <int value="0" label="Back"/> <int value="1" label="Forward"/> <int value="2" label="Stop"/> @@ -7380,7 +7380,7 @@ <int value="7" label="New Tab"/> </enum> -<enum name="DefaultWebClientState" type="int"> +<enum name="DefaultWebClientState"> <int value="0" label="Not default">Chrome is not the default web client.</int> <int value="1" label="Is default">Chrome is the default web client.</int> <int value="2" label="Unknown default"> @@ -7388,7 +7388,7 @@ </int> </enum> -<enum name="DelayBasedEchoQuality" type="int"> +<enum name="DelayBasedEchoQuality"> <int value="0" label="Good delays"> Echo Cancellation quality most likely good. </int> @@ -7399,12 +7399,12 @@ <int value="3" label="Invalid delays">Insufficient amount of data.</int> </enum> -<enum name="DeprecatedAcceleratorUsage" type="int"> +<enum name="DeprecatedAcceleratorUsage"> <int value="0" label="Deprecated key accelerator is used"/> <int value="1" label="New key accelerator is used"/> </enum> -<enum name="DesktopCaptureCounters" type="int"> +<enum name="DesktopCaptureCounters"> <int value="0" label="Screen capturer created."/> <int value="1" label="Window capturer created."/> <int value="2" label="First screen capture call succeeded."/> @@ -7420,7 +7420,7 @@ <int value="12" label="Tab capturer created without audio capturer."/> </enum> -<enum name="DesktopIOSPromotionDismissalReason" type="int"> +<enum name="DesktopIOSPromotionDismissalReason"> <int value="0" label="Focus lost."/> <int value="1" label="No thanks clicked."/> <int value="2" label="Close button clicked."/> @@ -7428,7 +7428,7 @@ <int value="4" label="Learn more link clicked."/> </enum> -<enum name="DesktopIOSPromotionEntryPoint" type="int"> +<enum name="DesktopIOSPromotionEntryPoint"> <int value="1" label="Save Passwords new bubble."/> <int value="2" label="Bookmarks new bubble."/> <int value="3" label="Bookmarks footnote."/> @@ -7436,40 +7436,40 @@ <int value="5" label="Footnote followup bubble"/> </enum> -<enum name="DesktopSearchRedirectionInfobarCloseAction" type="int"> +<enum name="DesktopSearchRedirectionInfobarCloseAction"> <int value="0" label="Clicked the 'Manage search settings' link"/> <int value="1" label="Clicked the dismiss button"/> <int value="2" label="InfoBar dismissed implicitly (no interaction)"/> </enum> -<enum name="DesktopSearchURLAction" type="int"> +<enum name="DesktopSearchURLAction"> <int value="0" label="No redirection - Feature disabled"/> <int value="1" label="No redirection - Default search engine is Bing"/> <int value="2" label="No redirection - Default search engine is invalid"/> <int value="3" label="Redirection to the default search engine"/> </enum> -<enum name="DeviceIdMismatch" type="int"> +<enum name="DeviceIdMismatch"> <int value="0" label="BOTH_NONEMPTY"/> <int value="1" label="SYNC_EMPTY"/> <int value="2" label="PREF_EMPTY"/> </enum> -<enum name="DeviceOrientationSensorTypeAndroid" type="int"> +<enum name="DeviceOrientationSensorTypeAndroid"> <int value="0" label="Not Available"/> <int value="1" label="ROTATION_VECTOR"/> <int value="2" label="ACCELEROMETER + MAGNETIC_FIELD"/> <int value="3" label="GAME_ROTATION_VECTOR"/> </enum> -<enum name="DevicePermissionActions" type="int"> +<enum name="DevicePermissionActions"> <int value="0" label="AllowHttps"/> <int value="1" label="AllowHttp"/> <int value="2" label="Deny"/> <int value="3" label="Cancel"/> </enum> -<enum name="DevicesPageEvents" type="int"> +<enum name="DevicesPageEvents"> <int value="0" label="OPENED"/> <int value="1" label="LOG_IN_STARTED_FROM_REGISTER_PROMO"/> <int value="2" label="LOG_IN_STARTED_FROM_DEVICE_LIST_PROMO"/> @@ -7485,7 +7485,7 @@ <int value="12" label="LOG_IN_STARTED_FROM_REGISTER_OVERLAY_PROMO"/> </enum> -<enum name="DeviceTechnologyType" type="int"> +<enum name="DeviceTechnologyType"> <int value="0" label="Unknown"/> <int value="1" label="Ethernet"/> <int value="2" label="WiFi"/> @@ -7493,7 +7493,7 @@ <int value="4" label="Cellular"/> </enum> -<enum name="DevToolsAction" type="int"> +<enum name="DevToolsAction"> <int value="1" label="Window docked"/> <int value="2" label="Window undocked"/> <int value="3" label="Scripts breakpoint set"/> @@ -7523,7 +7523,7 @@ <int value="27" label="Style rule copied"/> </enum> -<enum name="DevToolsPanel" type="int"> +<enum name="DevToolsPanel"> <int value="1" label="Elements"/> <int value="2" label="Resources"/> <int value="3" label="Network"/> @@ -7544,7 +7544,7 @@ <int value="18" label="Audits"/> </enum> -<enum name="DevToolsSetting" type="int"> +<enum name="DevToolsSetting"> <int value="1" label="Elements DOM wrap on"/> <int value="2" label="Elements DOM wrap off"/> <int value="3" label="Console monitor XHR on"/> @@ -7555,20 +7555,20 @@ <int value="8" label="Network show large rows off"/> </enum> -<enum name="DiagnosticsRecoveryRun" type="int"> +<enum name="DiagnosticsRecoveryRun"> <int value="0" label="Recovery not run"/> <int value="1" label="Recovery run because of crash"/> <int value="2" label="Recovery run by user"/> </enum> -<enum name="DiagnosticsResult" type="int"> +<enum name="DiagnosticsResult"> <int value="0" label="Not run (regular startup)"/> <int value="1" label="Success (crash startup)"/> <int value="2" label="Failure (crash startup)"/> <int value="3" label="Skipped (crash startup)"/> </enum> -<enum name="DiagnosticsTestName" type="int"> +<enum name="DiagnosticsTestName"> <int value="0" label="Conflicting DLLs Test"/> <int value="1" label="Disk Space Test"/> <int value="2" label="Install Type Test"/> @@ -7594,7 +7594,7 @@ <int value="22" label="SQLite Integrity Top Sites Test"/> </enum> -<enum name="DialogName" type="int"> +<enum name="DialogName"> <int value="0" label="Unknown"/> <int value="1" label="Translate"/> <int value="2" label="Bookmark"/> @@ -7677,19 +7677,19 @@ <int value="79" label="Zoom"/> </enum> -<enum name="DidNavigateToAd" type="int"> +<enum name="DidNavigateToAd"> <int value="0" label="Navigated to Non-Ad"/> <int value="1" label="Navigated to Ad"/> </enum> -<enum name="DifferentPrimaryAccounts" type="int"> +<enum name="DifferentPrimaryAccounts"> <int value="0" label="Primary Accounts the same"/> <int value="1" label="(obsolete) Primary Accounts different"/> <int value="2" label="No GAIA account in cookie jar"/> <int value="3" label="Primary accounts present but different"/> </enum> -<enum name="DircryptoMigrationEndStatus" type="int"> +<enum name="DircryptoMigrationEndStatus"> <int value="1" label="New migration failed (generic failure)"/> <int value="2" label="New migration succeeded"/> <int value="3" label="Resumed migration failed (generic failure)"/> @@ -7702,7 +7702,7 @@ <int value="10" label="Resumed migration failed (file error EIO on open)"/> </enum> -<enum name="DircryptoMigrationFailedOperationType" type="int"> +<enum name="DircryptoMigrationFailedOperationType"> <int value="1" label="Other"/> <int value="2" label="open(src_file)"/> <int value="3" label="open(dest_file)"/> @@ -7720,7 +7720,7 @@ <int value="15" label="non fatal open(src_file)"/> </enum> -<enum name="DircryptoMigrationFailedPathType" type="int"> +<enum name="DircryptoMigrationFailedPathType"> <int value="1" label="Other"/> <int value="2" label="Android Other"/> <int value="3" label="Android Cache"/> @@ -7729,30 +7729,30 @@ <int value="6" label="GCache (Google Drive Cache)"/> </enum> -<enum name="DircryptoMigrationStartStatus" type="int"> +<enum name="DircryptoMigrationStartStatus"> <int value="1" label="Migration started"/> <int value="2" label="Migration resumed"/> </enum> -<enum name="DirectoryDatabaseRepairResult" type="int"> +<enum name="DirectoryDatabaseRepairResult"> <int value="0" label="Succeeded"/> <int value="1" label="Failed"/> </enum> -<enum name="DirectWriteFontFallbackResult" type="int"> +<enum name="DirectWriteFontFallbackResult"> <int value="0" label="Failed: no font matched"/> <int value="1" label="Success: mapped from cache"/> <int value="2" label="Success: mapped using IPC"/> </enum> -<enum name="DirectWriteFontLoaderType" type="int"> +<enum name="DirectWriteFontLoaderType"> <int value="0" label="File: system font directory"/> <int value="1" label="File: outside sandbox whitelist"/> <int value="2" label="Non-file loader"/> <int value="3" label="Font was missing require styles"/> </enum> -<enum name="DirectWriteFontProxyError" type="int"> +<enum name="DirectWriteFontProxyError"> <int value="0" label="FindFamily: send failed"/> <int value="1" label="GetFamilyCount: send failed"/> <int value="2" label="CreateEnumeratorFromKey: invalid key"/> @@ -7761,7 +7761,7 @@ <int value="5" label="FontFileStream: failed to created mapped file"/> </enum> -<enum name="DirectWriteLoadFamilyResult" type="int"> +<enum name="DirectWriteLoadFamilyResult"> <int value="0" label="Success: single family"/> <int value="1" label="Success: matched from collection"/> <int value="2" label="Error: multiple families"/> @@ -7769,7 +7769,7 @@ <int value="4" label="Error: failed to create collection"/> </enum> -<enum name="DirectWriteMessageFilterError" type="int"> +<enum name="DirectWriteMessageFilterError"> <int value="0" label="OnGetFontFiles: GetFont failed"/> <int value="1" label="OnGetFontFiles: AddFilesForFont failed"/> <int value="2" label="OnGetFontFiles: GetFontFamily failed"/> @@ -7785,26 +7785,26 @@ <int value="12" label="AddLocalFile: get path failed"/> </enum> -<enum name="DisplayLinkInstallationStatus" type="int"> +<enum name="DisplayLinkInstallationStatus"> <int value="0" label="DisplayLink not installed"/> <int value="1" label="7.1 or earlier"/> <int value="2" label="7.2 or later"/> </enum> -<enum name="DistillableType" type="int"> +<enum name="DistillableType"> <int value="0" label="Not distillable"/> <int value="1" label="Non-mobile-friendly distillable"/> <int value="2" label="Mobile-friendly distillable"/> </enum> -<enum name="DistillableType2" type="int"> +<enum name="DistillableType2"> <int value="0" label="Non-mobile-friendly, not distillable"/> <int value="1" label="Mobile-friendly, not distillable"/> <int value="2" label="Non-mobile-friendly, distillable"/> <int value="3" label="Mobile-friendly, distillable"/> </enum> -<enum name="DistillRejection" type="int"> +<enum name="DistillRejection"> <int value="0" label="Not an article"/> <int value="1" label="Mobile-friendly"/> <int value="2" label="Domain is blacklisted"/> @@ -7812,7 +7812,7 @@ <int value="4" label="Not rejected"/> </enum> -<enum name="DllHash" type="int"> +<enum name="DllHash"> <!-- Generated by chrome_elf/dll_hash/dll_hash_main.cc --> <int value="26393601" label="wajam_goblin_64.dll"/> @@ -7855,33 +7855,33 @@ <int value="2132270559" label="libsvn_tsvn32.dll"/> </enum> -<enum name="DNS.AddressListDeltaType" type="int"> +<enum name="DNS.AddressListDeltaType"> <int value="0" label="Same addresses in the same order"/> <int value="1" label="Same addresses in a different order"/> <int value="2" label="Some but not all addresses in common"/> <int value="3" label="No addresses in common"/> </enum> -<enum name="DNS.HostCache.EraseReason" type="int"> +<enum name="DNS.HostCache.EraseReason"> <int value="0" label="Entry evicted"/> <int value="1" label="Cache cleared"/> <int value="2" label="Cache destroyed"/> </enum> -<enum name="DNS.HostCache.LookupOutcome" type="int"> +<enum name="DNS.HostCache.LookupOutcome"> <int value="0" label="Miss (absent)"/> <int value="1" label="Miss (stale when not requested)"/> <int value="2" label="Hit (valid)"/> <int value="3" label="Hit (stale when requested)"/> </enum> -<enum name="DNS.HostCache.SetOutcome" type="int"> +<enum name="DNS.HostCache.SetOutcome"> <int value="0" label="Inserted new entry"/> <int value="1" label="Updated valid entry"/> <int value="2" label="Updated stale entry"/> </enum> -<enum name="DNS.StaleHostResolverRequestOutcome" type="int"> +<enum name="DNS.StaleHostResolverRequestOutcome"> <int value="0" label="Returned synchronously (cache, hosts, IP literal etc.)"/> <int value="1" @@ -7893,12 +7893,12 @@ <int value="5" label="Canceled; stale cached result was available."/> </enum> -<enum name="DNSEmptyAddressListAndNoError" type="int"> +<enum name="DNSEmptyAddressListAndNoError"> <int value="0" label="Error reported or Address List is not empty"/> <int value="1" label="Success reported but Address List is empty"/> </enum> -<enum name="DnsProbe.JobResult" type="int"> +<enum name="DnsProbe.JobResult"> <int value="0" label="SERVERS_UNKNOWN"/> <int value="1" label="SERVERS_CORRECT"/> <int value="2" label="SERVERS_INCORRECT"/> @@ -7906,14 +7906,14 @@ <int value="4" label="SERVERS_UNREACHABLE"/> </enum> -<enum name="DnsProbe.ObsoleteProbeResult" type="int"> +<enum name="DnsProbe.ObsoleteProbeResult"> <int value="0" label="INCONCLUSIVE"/> <int value="1" label="NO_INTERNET"/> <int value="2" label="BAD_CONFIG"/> <int value="3" label="NXDOMAIN"/> </enum> -<enum name="DnsProbe.ProbeStatus" type="int"> +<enum name="DnsProbe.ProbeStatus"> <int value="0" label="POSSIBLE"/> <int value="1" label="NOT_RUN"/> <int value="2" label="STARTED"/> @@ -7923,7 +7923,7 @@ <int value="6" label="FINISHED_NXDOMAIN"/> </enum> -<enum name="DnsProbe.SystemIsLocalhost" type="int"> +<enum name="DnsProbe.SystemIsLocalhost"> <int value="0" label="Not just 127.0.0.1"> 127.0.0.1 was not the only nameserver in the system DNS config. </int> @@ -7932,7 +7932,7 @@ </int> </enum> -<enum name="DockedAction" type="int"> +<enum name="DockedAction"> <int value="0" label="None"/> <int value="1" label="Dock"/> <int value="2" label="Undock"/> @@ -7945,19 +7945,19 @@ <int value="9" label="Close"/> </enum> -<enum name="DockedActionSource" type="int"> +<enum name="DockedActionSource"> <int value="0" label="Unknown"/> <int value="1" label="Mouse"/> <int value="2" label="Touch"/> <int value="3" label="Keyboard"/> </enum> -<enum name="DocumentStateForDeferredLoading" type="int"> +<enum name="DocumentStateForDeferredLoading"> <int value="0" label="Created"/> <int value="1" label="WouldLoadBecauseVisible"/> </enum> -<enum name="DocumentStateForDeferredLoadingV2" type="int"> +<enum name="DocumentStateForDeferredLoadingV2"> <int value="0" label="Created"/> <int value="1" label="WouldLoadOutOfProcess"/> <int value="2" label="WouldLoadDisplayNone"/> @@ -7967,7 +7967,7 @@ <int value="6" label="WouldLoadVisible"/> </enum> -<enum name="DocumentStateForDeferredLoadingV3" type="int"> +<enum name="DocumentStateForDeferredLoadingV3"> <int value="0" label="Created"/> <int value="1" label="WouldLoadOutOfProcess"/> <int value="2" label="WouldLoadDisplayNone"/> @@ -7978,7 +7978,7 @@ <int value="7" label="WouldLoadVisible"/> </enum> -<enum name="DocumentStateForDeferredLoadingV4" type="int"> +<enum name="DocumentStateForDeferredLoadingV4"> <int value="0" label="Invalid"/> <int value="1" label="Created"/> <int value="2" label="WouldLoad3ScreensAway"/> @@ -7988,7 +7988,7 @@ <int value="6" label="WouldLoadNoParent"/> </enum> -<enum name="DocumentWriteGatedEvaluation" type="int"> +<enum name="DocumentWriteGatedEvaluation"> <int value="0" label="Script too long"/> <int value="1" label="No likely external script write"/> <int value="2" label="Looping construct found"/> @@ -7996,13 +7996,13 @@ <int value="4" label="Script uses non-determinism"/> </enum> -<enum name="DocumentWriteLoadingBehavior" type="int"> +<enum name="DocumentWriteLoadingBehavior"> <int value="0" label="A script on the page is blockable"/> <int value="1" label="Reload scenario, so not blockable"/> <int value="2" label="Same Site Different Scheme Script"/> </enum> -<enum name="DomainBoundCerts.DBLoadStatus" type="int"> +<enum name="DomainBoundCerts.DBLoadStatus"> <int value="0" label="Database path doesn't exist and couldn't be created"/> <int value="1" label="Unable to open database"/> <int value="2" label="Failed to migrate db to current version"/> @@ -8013,7 +8013,7 @@ label="Loaded existing db, but failed to load one or more keys"/> </enum> -<enum name="DomainBoundCerts.GetCertResult" type="int"> +<enum name="DomainBoundCerts.GetCertResult"> <int value="0" label="SYNC_SUCCESS"/> <int value="1" label="ASYNC_SUCCESS"/> <int value="2" label="ASYNC_CANCELLED"/> @@ -8027,7 +8027,7 @@ <int value="10" label="WORKER_FAILURE"/> </enum> -<enum name="DomainBoundCerts.Support" type="int"> +<enum name="DomainBoundCerts.Support"> <int value="0" label="DISABLED"/> <int value="1" label="CLIENT_ONLY"/> <int value="2" label="CLIENT_AND_SERVER"/> @@ -8044,12 +8044,12 @@ </int> </enum> -<enum name="DomainReliability.BooleanFailover" type="int"> +<enum name="DomainReliability.BooleanFailover"> <int value="0" label="Used first collector"/> <int value="1" label="Failed over to another collector"/> </enum> -<enum name="DoodleConfigDownloadOutcome" type="int"> +<enum name="DoodleConfigDownloadOutcome"> <summary> These values are defined in the DownloadOutcome enum in components/doodle/doodle_service.h. @@ -8064,13 +8064,13 @@ <int value="7" label="Request ignored, min refresh interval not passed"/> </enum> -<enum name="DoubleGetExperimentMethods" type="int"> +<enum name="DoubleGetExperimentMethods"> <int value="0" label="POST"/> <int value="1" label="GET_CACHABLE"/> <int value="2" label="GET_NON_CACHABLE"/> </enum> -<enum name="DownEventDestination" type="int"> +<enum name="DownEventDestination"> <int value="0" label="Others, everything except browser and apps"/> <int value="1" label="Inside the browser frame"/> <int value="2" label="Regular Chrome app"/> @@ -8078,19 +8078,19 @@ <int value="4" label="Default note-taking app (deprecated)"/> </enum> -<enum name="DownEventFormFactor" type="int"> +<enum name="DownEventFormFactor"> <int value="0" label="Clamshell"/> <int value="1" label="Touchview"/> </enum> -<enum name="DownEventSource" type="int"> +<enum name="DownEventSource"> <int value="0" label="Unknown"/> <int value="1" label="Mouse"/> <int value="2" label="Stylus"/> <int value="3" label="Touch"/> </enum> -<enum name="DownloadConnectionSecurity" type="int"> +<enum name="DownloadConnectionSecurity"> <int value="0" label="Final download url and the redirects before it all use https"/> <int value="1" label="Final download url uses http, redirects all use https"/> @@ -8103,7 +8103,7 @@ <int value="4" label="Final download url uses scheme other than http/https"/> </enum> -<enum name="DownloadContentDisposition" type="int"> +<enum name="DownloadContentDisposition"> <int value="0" label="Content-Disposition header present"/> <int value="1" label="Valid"/> <int value="2" label="Has disposition-type"/> @@ -8117,7 +8117,7 @@ <int value="10" label="Has 'name' attribute only (Obsolete 04/2015)"/> </enum> -<enum name="DownloadContentType" type="int"> +<enum name="DownloadContentType"> <int value="0" label="UNRECOGNIZED"/> <int value="1" label="TEXT"/> <int value="2" label="IMAGE"/> @@ -8134,7 +8134,7 @@ <int value="13" label="CRX"/> </enum> -<enum name="DownloadCountType" type="int"> +<enum name="DownloadCountType"> <int value="0" label="Initiated by Navigation (Obsolete)"/> <int value="1" label="Initiated by Context Menu (Obsolete)"/> <int value="2" label="Initiated by SavePackage Failure (Obsolete)"/> @@ -8162,14 +8162,14 @@ <int value="24" label="No bytes received after content length mismatch"/> </enum> -<enum name="DownloadDatabaseRecordDroppedType" type="int"> +<enum name="DownloadDatabaseRecordDroppedType"> <int value="0" label="Bad State"/> <int value="1" label="Bad Danger Type"/> <int value="2" label="Bad ID"/> <int value="3" label="Duplicate ID"/> </enum> -<enum name="DownloadDOMEvent" type="int"> +<enum name="DownloadDOMEvent"> <int value="0" label="GetDownloads"/> <int value="1" label="OpenFile"/> <int value="2" label="Drag"/> @@ -8184,14 +8184,14 @@ <int value="11" label="Resume"/> </enum> -<enum name="DownloadFilePickerResult" type="int"> +<enum name="DownloadFilePickerResult"> <int value="0" label="SAME"/> <int value="1" label="DIFFERENT_DIR"/> <int value="2" label="DIFFERENT_NAME"/> <int value="3" label="CANCEL"/> </enum> -<enum name="DownloadFunctions" type="int"> +<enum name="DownloadFunctions"> <int value="0" label="download"/> <int value="1" label="search"/> <int value="2" label="pause"/> @@ -8210,7 +8210,7 @@ <int value="15" label="determine_filename"/> </enum> -<enum name="DownloadImageType" type="int"> +<enum name="DownloadImageType"> <int value="0" label="Unrecognized"/> <int value="1" label="GIF"/> <int value="2" label="JPEG"/> @@ -8220,12 +8220,12 @@ <int value="6" label="WEBP"/> </enum> -<enum name="DownloadInterruptedUnknownSizeType" type="int"> +<enum name="DownloadInterruptedUnknownSizeType"> <int value="0" label="Size Known"/> <int value="1" label="Size Unknown"/> </enum> -<enum name="DownloadItem.DangerousFileType" type="int"> +<enum name="DownloadItem.DangerousFileType"> <int value="0" label="unknown"/> <int value="1" label="ad"/> <int value="2" label="ade"/> @@ -8492,7 +8492,7 @@ <int value="263" label="ad"/> </enum> -<enum name="DownloadItem.DangerType" type="int"> +<enum name="DownloadItem.DangerType"> <int value="0" label="NOT_DANGEROUS"/> <int value="1" label="DANGEROUS_FILE"/> <int value="2" label="DANGEROUS_URL"/> @@ -8504,13 +8504,13 @@ <int value="8" label="POTENTIALLY_UNWANTED"/> </enum> -<enum name="DownloadOpenMethod" type="int"> +<enum name="DownloadOpenMethod"> <int value="0" label="Opened with plaform handler by default"/> <int value="1" label="Opened in browser by default"/> <int value="2" label="Opened with plaform handler by user choice"/> </enum> -<enum name="DownloadOriginStateOnResumption" type="int"> +<enum name="DownloadOriginStateOnResumption"> <int value="0" label="No changes"/> <int value="1" label="New redirects"/> <int value="2" label="New validators"/> @@ -8521,14 +8521,14 @@ <int value="7" label="New redirects + validators + Content-Disposition"/> </enum> -<enum name="DownloadPassKitResult" type="int"> +<enum name="DownloadPassKitResult"> <int value="0" label="Successful"/> <int value="1" label="Other Failure"/> <int value="2" label="Unauthorized Failure"/> <int value="3" label="Wrong MIME Type Failure"/> </enum> -<enum name="DownloadSavePackageEvent" type="int"> +<enum name="DownloadSavePackageEvent"> <int value="0" label="Started"/> <int value="1" label="Cancelled"/> <int value="2" label="Finished"/> @@ -8536,7 +8536,7 @@ <int value="4" label="Write to already failed file"/> </enum> -<enum name="DownloadSource" type="int"> +<enum name="DownloadSource"> <int value="0" label="Initiated by Save Package on Non-HTML content"/> <int value="1" label="Initiated by Drag-and-drop"/> <int value="2" label="Initiated by RPC from Renderer"/> @@ -8547,17 +8547,17 @@ <int value="6" label="Initiated by Automatic Resumption"/> </enum> -<enum name="DownloadUploadRequestedByServer" type="int"> +<enum name="DownloadUploadRequestedByServer"> <int value="0" label="No Upload"/> <int value="1" label="Upload Requested"/> </enum> -<enum name="DragDropEventSource" type="int"> +<enum name="DragDropEventSource"> <int value="0" label="Mouse"/> <int value="1" label="Touch"/> </enum> -<enum name="DriveApiErrorCode" type="int"> +<enum name="DriveApiErrorCode"> <!-- Generated from google_apis/drive/drive_api_error_codes.h --> <int value="200" label="HTTP_SUCCESS"/> @@ -8588,14 +8588,14 @@ <int value="1007" label="DRIVE_RESPONSE_TOO_LARGE"/> </enum> -<enum name="DriveCacheDBOpenStatus" type="int"> +<enum name="DriveCacheDBOpenStatus"> <int value="0" label="Success"/> <int value="1" label="Corrupt database"/> <int value="2" label="Unknown recoverable failure"/> <int value="3" label="Unrecoverable (disk full?) failure"/> </enum> -<enum name="DriveEntryKind" type="int"> +<enum name="DriveEntryKind"> <int value="0" label="Unknown"/> <int value="1" label="Item"/> <int value="2" label="Site"/> @@ -8610,7 +8610,7 @@ <int value="11" label="PDF"/> </enum> -<enum name="DriveFileFormat" type="int"> +<enum name="DriveFileFormat"> <int value="0" label="AAC"/> <int value="1" label="ASF"/> <int value="2" label="AVI"/> @@ -8637,7 +8637,7 @@ <int value="23" label="ZIP"/> </enum> -<enum name="DriveMetadataDBInitStatus" type="int"> +<enum name="DriveMetadataDBInitStatus"> <int value="0" label="Success"/> <int value="1" label="Not found"/> <int value="2" label="Corruption"/> @@ -8650,7 +8650,7 @@ <int value="9" label="Cannot open existing DB. Created new DB."/> </enum> -<enum name="DriveMetadataDBValidityCheckFailureReason" type="int"> +<enum name="DriveMetadataDBValidityCheckFailureReason"> <int value="0" label="Invalid header"/> <int value="1" label="Broken ID entry"/> <int value="2" label="Broken entry"/> @@ -8661,13 +8661,13 @@ <int value="7" label="Iterator error"/> </enum> -<enum name="DriveUploadProtocol" type="int"> +<enum name="DriveUploadProtocol"> <int value="0" label="Resumable"/> <int value="1" label="Multipart"/> <int value="2" label="Batch"/> </enum> -<enum name="DTLS_SRTPCryptoSuite" type="int"> +<enum name="DTLS_SRTPCryptoSuite"> <summary> DTLS/SRTP crypto suites from the IANA registry as specified at https://tools.ietf.org/html/rfc5764#section-4.1.2 @@ -8678,25 +8678,25 @@ <int value="6" label="SRTP_NULL_SHA1_32"/> </enum> -<enum name="DtlsHandshakeError" type="int"> +<enum name="DtlsHandshakeError"> <int value="0" label="Incompatible cipher suite"/> <int value="1" label="Unknown error"/> </enum> -<enum name="DumpOutcome" type="int"> +<enum name="DumpOutcome"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Unknown"/> </enum> -<enum name="DxgiFramePresentationMode" type="int"> +<enum name="DxgiFramePresentationMode"> <int value="0" label="Composed"/> <int value="1" label="Overlay"/> <int value="2" label="None (Unknown)"/> <int value="3" label="Composition Failure"/> </enum> -<enum name="EAPInnerProtocol" type="int"> +<enum name="EAPInnerProtocol"> <int value="0" label="UNKNOWN"/> <int value="1" label="NONE"/> <int value="2" label="PEAP-MD5"/> @@ -8709,7 +8709,7 @@ <int value="9" label="TTLS-CHAP"/> </enum> -<enum name="EAPOuterProtocol" type="int"> +<enum name="EAPOuterProtocol"> <int value="0" label="UNKNOWN"/> <int value="1" label="LEAP"/> <int value="2" label="PEAP"/> @@ -8717,7 +8717,7 @@ <int value="4" label="TTLS"/> </enum> -<enum name="EasyUnlockAuthEvent" type="int"> +<enum name="EasyUnlockAuthEvent"> <int value="0" label="Smart Lock success"/> <int value="1" label="Smart Lock failure"/> <int value="2" label="Password entry: No pairing"/> @@ -8740,13 +8740,13 @@ <int value="19" label="Password entry: Phone locked and tx power too high"/> </enum> -<enum name="EasyUnlockBluetoothType" type="int"> +<enum name="EasyUnlockBluetoothType"> <int value="0" label="No adapter"/> <int value="1" label="Normal"/> <int value="2" label="Low energy"/> </enum> -<enum name="EasyUnlockButton" type="int"> +<enum name="EasyUnlockButton"> <int value="0" label="Setup app launches"/> <int value="1" label="Find device"/> <int value="2" label="Pair device"/> @@ -8756,7 +8756,7 @@ <int value="6" label="Dismiss ('done')"/> </enum> -<enum name="EasyUnlockDeviceIneligibilityReason" type="int"> +<enum name="EasyUnlockDeviceIneligibilityReason"> <int value="0" label="Unrecognized reason"> The server reported a reason that the client is not aware of. This should only be recorded if the client's list of possible reasons is out of date. @@ -8774,7 +8774,7 @@ <int value="9" label="No recent updates"/> </enum> -<enum name="EasyUnlockDeviceModelHash" type="int"> +<enum name="EasyUnlockDeviceModelHash"> <int value="-1829584143" label="Motorola XT1097"/> <int value="-1429808627" label="HTC One"/> <int value="-1168032746" label="Motorola Nexus 6"/> @@ -8785,29 +8785,29 @@ <int value="1881443083" label="LGE Nexus 5"/> </enum> -<enum name="EasyUnlockDidUserManuallyUnlockPhone" type="int"> +<enum name="EasyUnlockDidUserManuallyUnlockPhone"> <int value="0" label="Never locked"/> <int value="1" label="Manually unlocked"/> </enum> -<enum name="EasyUnlockHasSecureScreenLock" type="int"> +<enum name="EasyUnlockHasSecureScreenLock"> <int value="0" label="Lacks secure screen lock"/> <int value="1" label="Has secure screen lock"/> </enum> -<enum name="EasyUnlockHasTrustAgentEnabled" type="int"> +<enum name="EasyUnlockHasTrustAgentEnabled"> <int value="0" label="No trust agents enabled"/> <int value="1" label="1+ trust agents enabled"/> </enum> -<enum name="EasyUnlockNotificationEvent" type="int"> +<enum name="EasyUnlockNotificationEvent"> <int value="0" label="Set up notification shown"/> <int value="1" label="Set up notification clicked"/> <int value="2" label="Try out notification shown"/> <int value="3" label="Try out notification clicked"/> </enum> -<enum name="EasyUnlockPromoNotificationEvent" type="int"> +<enum name="EasyUnlockPromoNotificationEvent"> <int value="0" label="Promo notification shown"/> <int value="1" label="Promo notification clicked"/> <int value="2" label="Promo notification dismissed"/> @@ -8815,7 +8815,7 @@ <int value="4" label="Setup completed successfully"/> </enum> -<enum name="EasyUnlockRemoteLockScreenState" type="int"> +<enum name="EasyUnlockRemoteLockScreenState"> <int value="0" label="Unknown state"/> <int value="1" label="Lock screen disabled, trust agent unsupported"/> <int value="2" label="Lock screen disabled, trust agent disabled"/> @@ -8825,7 +8825,7 @@ <int value="6" label="Lock screen enabled, trust agent enabled"/> </enum> -<enum name="EasyUnlockSetupState" type="int"> +<enum name="EasyUnlockSetupState"> <int value="0" label="Success"/> <int value="1" label="Scan (initial)"/> <int value="2" label="Scan (in progress)"/> @@ -8836,17 +8836,17 @@ <int value="7" label="Help"/> </enum> -<enum name="EasyUnlockTrialRunEvents" type="int"> +<enum name="EasyUnlockTrialRunEvents"> <int value="0" label="Trial run launched"/> <int value="1" label="User clicked lock icon"/> </enum> -<enum name="EasyUnlockUnlockEvent" type="int"> +<enum name="EasyUnlockUnlockEvent"> <int value="0" label="Screen unlocked (total)"/> <int value="1" label="Screen unlocked (via EasyUnlock)"/> </enum> -<enum name="ECDHECurves" type="int"> +<enum name="ECDHECurves"> <int value="21" label="P-224"/> <int value="23" label="P-256"/> <int value="24" label="P-384"/> @@ -8854,7 +8854,7 @@ <int value="29" label="X25519"/> </enum> -<enum name="EGLDisplayType" type="int"> +<enum name="EGLDisplayType"> <int value="0" label="Default"/> <int value="1" label="SwiftShader"/> <int value="2" label="ANGLE WARP"/> @@ -8864,7 +8864,7 @@ <int value="6" label="ANGLE OpenGL ES"/> </enum> -<enum name="EmbeddedWorkerStartingPhase" type="int"> +<enum name="EmbeddedWorkerStartingPhase"> <int value="0" label="NOT_STARTING"/> <int value="1" label="ALLOCATING_PROCESS"/> <int value="2" label="REGISTERING_TO_DEVTOOLS"/> @@ -8877,7 +8877,7 @@ <int value="9" label="SCRIPT_READ_FINISHED"/> </enum> -<enum name="EncodingMethod" type="int"> +<enum name="EncodingMethod"> <int value="0" label="UNKNOWN"/> <int value="1" label="Big5"/> <int value="2" label="EUC-JP"/> @@ -8917,7 +8917,7 @@ <int value="36" label="windows-874"/> </enum> -<enum name="EnCrossCLD3LanguageCode" type="int"> +<enum name="EnCrossCLD3LanguageCode"> <summary> Hash values for strings of the form "x,y", where x is either a common English language BCP47 code or "other", and y is a language @@ -9970,7 +9970,7 @@ <int value="2144565498" label="en-ZA,bs"/> </enum> -<enum name="EnhancedBookmarkViewMode" type="int"> +<enum name="EnhancedBookmarkViewMode"> <obsolete> Deprecated 9/2015. </obsolete> @@ -9979,14 +9979,14 @@ <int value="2" label="Grid view mode"/> </enum> -<enum name="EnrollmentStatus" type="int"> +<enum name="EnrollmentStatus"> <int value="0" label="Non-managed"/> <int value="1" label="Managed EDU (Deprecated)"/> <int value="2" label="Managed"/> <int value="3" label="Error"/> </enum> -<enum name="EnterpriseAttributesTPMConsistencyType" type="int"> +<enum name="EnterpriseAttributesTPMConsistencyType"> <int value="0" label="no attributes, other mode, TPM unlocked"> valid: machine in pristine state </int> @@ -10016,7 +10016,7 @@ <int value="8" label="TPM unreachable">error: cryptohomed unreachable</int> </enum> -<enum name="EnterpriseCheckError" type="int"> +<enum name="EnterpriseCheckError"> <summary> Defined as DomainCheckErrors in components/policy/core/common/policy_loader_win.cc. @@ -10025,7 +10025,7 @@ <int value="1" label="Cound not bind to domain controller."/> </enum> -<enum name="EnterpriseDeviceManagementStatus" type="int"> +<enum name="EnterpriseDeviceManagementStatus"> <summary> Status codes produced by DeviceManagementService for requests made to the device management server as defined in @@ -10049,7 +10049,7 @@ <int value="902" label="SERVICE_POLICY_NOT_FOUND"/> </enum> -<enum name="EnterpriseDMServerRequestSuccess" type="int"> +<enum name="EnterpriseDMServerRequestSuccess"> <summary> Number of DeviceManagementServer request retries as defined in components/policy/core/common/cloud/device_management_service.cc. @@ -10062,7 +10062,7 @@ <int value="11" label="Server returned error"/> </enum> -<enum name="EnterpriseDMTokenType" type="int"> +<enum name="EnterpriseDMTokenType"> <summary> Result of DMToken operations as defined in components/policy/core/common/cloud/enterprise_metrics.h. @@ -10109,7 +10109,7 @@ </int> </enum> -<enum name="EnterpriseDomainRegex" type="int"> +<enum name="EnterpriseDomainRegex"> <summary>Which domain regex generated an ICU error.</summary> <int value="0" label="aol"/> <int value="1" label="googlemail"/> @@ -10123,7 +10123,7 @@ <int value="9" label="yandex"/> </enum> -<enum name="EnterpriseEnrollmentType" type="int"> +<enum name="EnterpriseEnrollmentType"> <summary> Result of device enrollment as defined in components/policy/core/common/cloud/enterprise_metrics.h. @@ -10311,7 +10311,7 @@ </int> </enum> -<enum name="EnterprisePolicies" type="int"> +<enum name="EnterprisePolicies"> <!-- Generated from components/policy/resources/policy_templates.json --> <int value="1" label="HomepageLocation"/> @@ -10687,7 +10687,7 @@ <int value="371" label="DownloadRestrictions"/> </enum> -<enum name="EnterprisePolicyInvalidations" type="int"> +<enum name="EnterprisePolicyInvalidations"> <summary> Defined as PolicyInvalidationType in components/policy/core/common/cloud/enterprise_metrics.h. @@ -10698,7 +10698,7 @@ <int value="4" label="Payload; expired"/> </enum> -<enum name="EnterprisePolicyKeyVerification" type="int"> +<enum name="EnterprisePolicyKeyVerification"> <summary> Defined as MetricPolicyKeyVerification in components/policy/core/common/cloud/cloud_policy_validator.cc. @@ -10718,7 +10718,7 @@ </int> </enum> -<enum name="EnterprisePolicyLoadStatus" type="int"> +<enum name="EnterprisePolicyLoadStatus"> <summary> Status codes produced by the policy loaders that pull policy settings from the platform-specific management infrastructure, such as Windows Group @@ -10750,7 +10750,7 @@ <int value="8" label="PARSE_ERROR">Parse error.</int> </enum> -<enum name="EnterprisePolicyRefresh" type="int"> +<enum name="EnterprisePolicyRefresh"> <summary> Defined as MetricPolicyRefresh in components/policy/core/common/cloud/enterprise_metrics.h. @@ -10762,7 +10762,7 @@ <int value="4" label="Invalidated; Unchanged"/> </enum> -<enum name="EnterprisePolicyType" type="int"> +<enum name="EnterprisePolicyType"> <summary> Result of Policy operations as defined as MetricPolicy in components/policy/core/common/cloud/enterprise_metrics.h. @@ -10825,7 +10825,7 @@ <int value="18" label="Store Failed">Caching a policy to disk failed.</int> </enum> -<enum name="EnterpriseRetrievePolicyResponseType" type="int"> +<enum name="EnterpriseRetrievePolicyResponseType"> <summary> Status codes produced by SessionManagerClient for policy retrieval requests. Corresponds to RetrievePolicyResponseType in @@ -10837,7 +10837,7 @@ <int value="3" label="Failed to retrieve policy data in session manager"/> </enum> -<enum name="EnterpriseUploadJobSuccess" type="int"> +<enum name="EnterpriseUploadJobSuccess"> <summary> Number of UploadJob retries as defined in chrome/browser/chromeos/policy/upload_job_impl.cc. @@ -10850,7 +10850,7 @@ <int value="11" label="Request interrupted"/> </enum> -<enum name="EnterpriseUserSessionLogins" type="int"> +<enum name="EnterpriseUserSessionLogins"> <summary> Types of sign-in events as defined in chrome/browser/chromeos/login/enterprise_user_session_metrics.h @@ -10862,7 +10862,7 @@ <int value="4" label="Automatic kiosk session"/> </enum> -<enum name="ErrorCodesGetAdaptersAddresses" type="int"> +<enum name="ErrorCodesGetAdaptersAddresses"> <int value="8" label="ERROR_NOT_ENOUGH_MEMORY"/> <int value="87" label="ERROR_INVALID_PARAMETER"/> <int value="111" label="ERROR_BUFFER_OVERFLOW"/> @@ -10870,7 +10870,7 @@ <int value="1228" label="ERROR_ADDRESS_NOT_ASSOCIATED"/> </enum> -<enum name="ErrorCodesGetaddrinfo_All" type="int"> +<enum name="ErrorCodesGetaddrinfo_All"> <int value="1" label="EAI_BADFLAGS(L)"/> <int value="2" label="EAI_NONAME(L) EAI_AGAIN(M)"/> <int value="3" label="EAI_AGAIN(L) EAI_BADFLAGS(M)"/> @@ -10894,7 +10894,7 @@ <int value="11004" label="WSANO_DATA"/> </enum> -<enum name="ErrorCodesGetaddrinfo_Linux" type="int"> +<enum name="ErrorCodesGetaddrinfo_Linux"> <int value="1" label="EAI_BADFLAGS"/> <int value="2" label="EAI_NONAME"/> <int value="3" label="EAI_AGAIN"/> @@ -10909,7 +10909,7 @@ <int value="12" label="EAI_OVERFLOW"/> </enum> -<enum name="ErrorCodesGetaddrinfo_Mac" type="int"> +<enum name="ErrorCodesGetaddrinfo_Mac"> <int value="1" label="EAI_ADDRFAMILY"/> <int value="2" label="EAI_AGAIN"/> <int value="3" label="EAI_BADFLAGS"/> @@ -10926,7 +10926,7 @@ <int value="14" label="EAI_OVERFLOW"/> </enum> -<enum name="ErrorCodesGetaddrinfo_Win" type="int"> +<enum name="ErrorCodesGetaddrinfo_Win"> <int value="6" label="WSA_INVALID_HANDLE"/> <int value="8" label="WSA_NOT_ENOUGH_MEMORY or EAI_SERVICE"/> <int value="10022" label="WSAEINVAL"/> @@ -10940,7 +10940,7 @@ <int value="11004" label="WSANO_DATA"/> </enum> -<enum name="ErrorPageButton" type="int"> +<enum name="ErrorPageButton"> <int value="0" label="NO_BUTTON"/> <int value="1" label="RELOAD_BUTTON"/> <int value="2" label="SHOW_SAVED_COPY_BUTTON"/> @@ -10950,14 +10950,14 @@ <int value="6" label="SHOW_CACHED_PAGE_BUTTON"/> </enum> -<enum name="ErrorPageUnexpectedStates" type="int"> +<enum name="ErrorPageUnexpectedStates"> <int value="0" label="OK"/> <int value="1" label="NON_ERROR_PAGE_URL"/> <int value="2" label="NO_ERROR_INFO"/> <int value="3" label="NON_ERROR_PAGE_URL_AND_NO_ERROR_INFO"/> </enum> -<enum name="EVCTCompliance" type="int"> +<enum name="EVCTCompliance"> <obsolete> Deprecated 06/2017. </obsolete> @@ -10970,7 +10970,7 @@ <int value="5" label="Not compliant because the build is not timely"/> </enum> -<enum name="EventHitTest" type="int"> +<enum name="EventHitTest"> <int value="0" label="Miss, not found in cache."/> <int value="1" label="Miss, explicitly avoided."/> <int value="2" label="Miss, validity region matches; type doesn't."/> @@ -10978,7 +10978,7 @@ <int value="4" label="Hit, region matched."/> </enum> -<enum name="EventHitTestValidity" type="int"> +<enum name="EventHitTestValidity"> <int value="0" label="Valid, exact match."/> <int value="1" label="Valid, region match."/> <int value="2" label="Incorrect, exact match (rect query)."/> @@ -10987,7 +10987,7 @@ <int value="5" label="Incorrect, region match (point query)."/> </enum> -<enum name="EventHitTestValidityScore" type="int"> +<enum name="EventHitTestValidityScore"> <int value="0" label="Nothing matched."/> <int value="1" label="Over widget matched."/> <int value="2" label="Scrollbar matched."/> @@ -10999,7 +10999,7 @@ <int value="128" label="Request type matched."/> </enum> -<enum name="EventResultType" type="int"> +<enum name="EventResultType"> <int value="0" label="Passive"/> <int value="1" label="Uncancelable"/> <int value="2" label="Suppressed"/> @@ -11009,12 +11009,12 @@ <int value="6" label="Forced Non-Blocking Due to Unresponsive Main Thread"/> </enum> -<enum name="EventTimestampValidity" type="int"> +<enum name="EventTimestampValidity"> <int value="0" label="Invalid time base"/> <int value="1" label="Valid time base"/> </enum> -<enum name="EVWhitelistStatus" type="int"> +<enum name="EVWhitelistStatus"> <obsolete> Deprecated 06/2017. </obsolete> @@ -11023,7 +11023,7 @@ <int value="2" label="Valid"/> </enum> -<enum name="ExecutionPhase" type="int"> +<enum name="ExecutionPhase"> <int value="0" label="UNINITIALIZED_PHASE"/> <int value="100" label="START_METRICS_RECORDING"/> <int value="200" label="CREATE_PROFILE"/> @@ -11034,7 +11034,7 @@ <int value="700" label="SHUTDOWN_COMPLETE"/> </enum> -<enum name="ExpectCTHeaderResult" type="int"> +<enum name="ExpectCTHeaderResult"> <int value="0" label="EXPECT_CT_HEADER_BAD_VALUE"/> <int value="1" label="EXPECT_CT_HEADER_BUILD_NOT_TIMELY"/> <int value="2" label="EXPECT_CT_HEADER_PRIVATE_ROOT"/> @@ -11044,20 +11044,20 @@ <int value="6" label="EXPECT_CT_HEADER_PROCESSED"/> </enum> -<enum name="ExtensionBackgroundPageType" type="int"> +<enum name="ExtensionBackgroundPageType"> <int value="0" label="None"/> <int value="1" label="Persistent"/> <int value="2" label="Event Page"/> </enum> -<enum name="ExtensionBubbleAction" type="int"> +<enum name="ExtensionBubbleAction"> <int value="0" label="Learn more"/> <int value="1" label="Execute"/> <int value="2" label="Dismiss by user action"/> <int value="3" label="Dismiss by deactivation"/> </enum> -<enum name="ExtensionCreationFlags" type="int"> +<enum name="ExtensionCreationFlags"> <int value="0" label="REQUIRE_KEY"/> <int value="1" label="REQUIRE_MODERN_MANIFEST_VERSION"/> <int value="2" label="ALLOW_FILE_ACCESS"/> @@ -11071,13 +11071,13 @@ <int value="10" label="WAS_INSTALLED_BY_OEM"/> </enum> -<enum name="ExtensionDisabledUIUserResponse" type="int"> +<enum name="ExtensionDisabledUIUserResponse"> <int value="0" label="IGNORED"/> <int value="1" label="REENABLE"/> <int value="2" label="UNINSTALL"/> </enum> -<enum name="ExtensionDisableReason" type="int"> +<enum name="ExtensionDisableReason"> <int value="0" label="UNKNOWN"/> <int value="1" label="USER_ACTION"/> <int value="2" label="PERMISSIONS_INCREASE"/> @@ -11097,7 +11097,7 @@ <int value="32768" label="CUSTODIAN_APPROVAL_REQUIRED"/> </enum> -<enum name="ExtensionEvents" type="int"> +<enum name="ExtensionEvents"> <!-- Generated from extensions/browser/extension_event_histogram_value.h --> <int value="0" label="UNKNOWN"/> @@ -11517,9 +11517,10 @@ <int value="407" label="ACCESSIBILITY_PRIVATE_ON_TWO_FINGER_TOUCH_STOP"/> <int value="408" label="MEDIA_PERCEPTION_PRIVATE_ON_MEDIA_PERCEPTION"/> <int value="409" label="NETWORKING_PRIVATE_ON_CERTIFICATE_LISTS_CHANGED"/> + <int value="410" label="LOCK_SCREEN_DATA_ON_DATA_ITEMS_AVAILABLE"/> </enum> -<enum name="ExtensionFileWriteResult" type="int"> +<enum name="ExtensionFileWriteResult"> <obsolete> Deprecated 10/2013. </obsolete> @@ -11529,12 +11530,12 @@ <int value="3" label="CANT_READ_CRX_FILE"/> </enum> -<enum name="ExtensionFromWebstoreInconcistencyEnum" type="int"> +<enum name="ExtensionFromWebstoreInconcistencyEnum"> <int value="0" label="Non-webstore update URL"/> <int value="1" label="External install location"/> </enum> -<enum name="ExtensionFunctions" type="int"> +<enum name="ExtensionFunctions"> <!-- Generated from extensions/browser/extension_function_histogram_value.h --> <int value="0" label="UNKNOWN"/> @@ -12746,15 +12747,20 @@ <int value="1177" label="NETWORKINGPRIVATE_GETCERTIFICATELISTS"/> <int value="1178" label="ACCESSIBILITY_PRIVATE_SETSWITCHACCESSKEYS"/> <int value="1179" label="FEEDBACKPRIVATE_READLOGSOURCE"/> + <int value="1180" label="LOCKSCREENDATA_CREATE"/> + <int value="1181" label="LOCKSCREENDATA_GETALL"/> + <int value="1182" label="LOCKSCREENDATA_GETCONTENT"/> + <int value="1183" label="LOCKSCREENDATA_SETCONTENT"/> + <int value="1184" label="LOCKSCREENDATA_DELETE"/> </enum> -<enum name="ExtensionIconState" type="int"> +<enum name="ExtensionIconState"> <int value="0" label="DISABLED"/> <int value="1" label="VISIBLE"/> <int value="2" label="OVERFLOWED"/> </enum> -<enum name="ExtensionInstallCause" type="int"> +<enum name="ExtensionInstallCause"> <int value="0" label="INSTALL_CAUSE_UNSET"/> <int value="1" label="INSTALL_CAUSE_USER_DOWNLOAD"/> <int value="2" label="INSTALL_CAUSE_UPDATE"/> @@ -12762,13 +12768,13 @@ <int value="4" label="INSTALL_CAUSE_AUTOMATION"/> </enum> -<enum name="ExtensionInstallPromptExperimentLinkAction" type="int"> +<enum name="ExtensionInstallPromptExperimentLinkAction"> <int value="0" label="Link is shown"/> <int value="1" label="Link is not shown"/> <int value="2" label="Link is clicked"/> </enum> -<enum name="ExtensionInstallPromptType" type="int"> +<enum name="ExtensionInstallPromptType"> <int value="0" label="Install prompt"/> <int value="1" label="Inline install prompt"/> <int value="2" label="Bundle install prompt"/> @@ -12780,20 +12786,20 @@ <int value="8" label="Remote install prompt"/> </enum> -<enum name="ExtensionInstallVerifierGetSignatureResult" type="int"> +<enum name="ExtensionInstallVerifierGetSignatureResult"> <int value="0" label="No signature (network error, etc)"/> <int value="1" label="Invalid signature"/> <int value="2" label="Valid signature"/> </enum> -<enum name="ExtensionInstallVerifierInitResult" type="int"> +<enum name="ExtensionInstallVerifierInitResult"> <int value="0" label="No value in prefs"/> <int value="1" label="Pref present but parsing failed"/> <int value="2" label="Invalid signature"/> <int value="3" label="Valid signature"/> </enum> -<enum name="ExtensionInstallVerifierMustRemainDisabled" type="int"> +<enum name="ExtensionInstallVerifierMustRemainDisabled"> <int value="0" label="VERIFIED"/> <int value="1" label="NOT_EXTENSION"/> <int value="2" label="UNPACKED"/> @@ -12808,20 +12814,20 @@ <int value="11" label="COMPONENT"/> </enum> -<enum name="ExtensionInstallVerifierStatus" type="int"> +<enum name="ExtensionInstallVerifierStatus"> <int value="0" label="NONE"/> <int value="1" label="BOOTSTRAP"/> <int value="2" label="ENFORCE"/> <int value="3" label="ENFORCE_STRICT"/> </enum> -<enum name="ExtensionLaunchType" type="int"> +<enum name="ExtensionLaunchType"> <int value="0" label="PINNED"/> <int value="1" label="REGULAR"/> <int value="2" label="FULLSCREEN"/> </enum> -<enum name="ExtensionLocation" type="int"> +<enum name="ExtensionLocation"> <int value="0" label="INVALID"/> <int value="1" label="INTERNAL"/> <int value="2" label="EXTERNAL_PREF"/> @@ -12835,7 +12841,7 @@ <int value="10" label="EXTERNAL_COMPONENT"/> </enum> -<enum name="ExtensionNotificationType" type="int"> +<enum name="ExtensionNotificationType"> <int value="0" label="NOTIFICATION_TYPE_SIMPLE"/> <int value="1" label="NOTIFICATION_TYPE_BASE_FORMAT"/> <int value="2" label="NOTIFICATION_TYPE_IMAGE"/> @@ -12844,7 +12850,7 @@ <int value="5" label="NOTIFICATION_TYPE_CUSTOM"/> </enum> -<enum name="ExtensionPermission" type="int"> +<enum name="ExtensionPermission"> <int value="0" label="UNKNOWN"/> <int value="1" label="NONE"/> <int value="2" label="BOOKMARKS"/> @@ -12876,7 +12882,7 @@ <int value="28" label="SOCKET_SPECIFIC_HOSTS"/> </enum> -<enum name="ExtensionPermission2" type="int"> +<enum name="ExtensionPermission2"> <!-- Generated from extensions/common/permissions/permission_message.h --> <int value="0" label="kUnknown"/> @@ -12966,7 +12972,7 @@ <int value="84" label="kUsersPrivate"/> </enum> -<enum name="ExtensionPermission3" type="int"> +<enum name="ExtensionPermission3"> <!-- Generated from extensions/common/permissions/api_permission.h --> <int value="0" label="kInvalid"/> @@ -13177,14 +13183,14 @@ <int value="205" label="kLockScreen"/> </enum> -<enum name="ExtensionServiceVerifyAllSuccess" type="int"> +<enum name="ExtensionServiceVerifyAllSuccess"> <int value="0" label="VERIFY_ALL_BOOTSTRAP_SUCCESS"/> <int value="1" label="VERIFY_ALL_BOOTSTRAP_FAILURE"/> <int value="2" label="VERIFY_ALL_NON_BOOTSTRAP_SUCCESS"/> <int value="3" label="VERIFY_ALL_NON_BOOTSTRAP_FAILURE"/> </enum> -<enum name="ExtensionType" type="int"> +<enum name="ExtensionType"> <int value="0" label="UNKNOWN"/> <int value="1" label="EXTENSION"/> <int value="2" label="THEME"/> @@ -13194,13 +13200,13 @@ <int value="6" label="PLATFORM_APP"/> </enum> -<enum name="ExtensionUninstallDialogAction" type="int"> +<enum name="ExtensionUninstallDialogAction"> <int value="0" label="Uninstall only"/> <int value="1" label="Uninstall and report abuse"/> <int value="2" label="Dialog canceled"/> </enum> -<enum name="ExtensionUninstallSource" type="int"> +<enum name="ExtensionUninstallSource"> <int value="0" label="Testing"/> <int value="1" label="Context menu"/> <int value="2" label="Permissions increase"/> @@ -13212,7 +13218,7 @@ <int value="8" label="Extension"/> </enum> -<enum name="ExtensionUnpackFailureReason" type="int"> +<enum name="ExtensionUnpackFailureReason"> <summary> Reasons the sandboxed extension unpacker can fail. See enum FailureReason in src/chrome/browser/extensions/sandboxed_extension_unpacker.h . @@ -13255,7 +13261,7 @@ <int value="35" label="CRX_EXPECTED_HASH_INVALID"/> </enum> -<enum name="ExternalDeviceAction" type="int"> +<enum name="ExternalDeviceAction"> <int value="0" label="Import to Drive"/> <int value="1" label="View files"/> <int value="2" label="View files (automatically)"/> @@ -13264,14 +13270,14 @@ <int value="5" label="Close (no action)"/> </enum> -<enum name="ExternalDisplayOpenResult" type="int"> +<enum name="ExternalDisplayOpenResult"> <int value="0" label="Success"/> <int value="1" label="Failed with EACCES (incorrect permission on device)"/> <int value="2" label="Failed with ENOENT (device missing)"/> <int value="3" label="Failed for some other reason"/> </enum> -<enum name="ExternalDisplayReceiveResult" type="int"> +<enum name="ExternalDisplayReceiveResult"> <int value="0" label="Success"/> <int value="1" label="ioctl() to I2C device failed"/> <int value="2" label="Bad message checksum"/> @@ -13283,12 +13289,12 @@ <int value="8" label="Maximum value of 0 in message"/> </enum> -<enum name="ExternalDisplaySendResult" type="int"> +<enum name="ExternalDisplaySendResult"> <int value="0" label="Success"/> <int value="1" label="ioctl() to I2C device failed"/> </enum> -<enum name="ExternalItemState" type="int"> +<enum name="ExternalItemState"> <int value="0" label="DEPRECATED_DISABLED"/> <int value="1" label="DEPRECATED_ENABLED"/> <int value="2" label="DISABLED (in webstore)"/> @@ -13299,13 +13305,13 @@ <int value="7" label="UNINSTALLED (not in webstore)"/> </enum> -<enum name="ExternallyConditionalizedType" type="int"> +<enum name="ExternallyConditionalizedType"> <int value="0" label="Cache entry requires validation"/> <int value="1" label="Cache entry usable"/> <int value="2" label="Cache entry validators don't match request"/> </enum> -<enum name="ExtractionStatus" type="int"> +<enum name="ExtractionStatus"> <summary>The status of metadata extraction for Appindexing.</summary> <int value="0" label="OK"/> <int value="1" label="Empty result"/> @@ -13313,26 +13319,26 @@ <int value="3" label="Wrong type in JSON top-level object"/> </enum> -<enum name="Exynos5250LotIdEnum" type="int"> +<enum name="Exynos5250LotIdEnum"> <int value="0" label="Fused device"/> <int value="1" label="Generic unfused device"/> <int value="2" label="Unfused; lot ID NZVPU"/> <int value="3" label="Unfused; lot ID NZVR7"/> </enum> -<enum name="FallbackDNSTestResult" type="int"> +<enum name="FallbackDNSTestResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> </enum> -<enum name="FallbackSSLVersion" type="int"> +<enum name="FallbackSSLVersion"> <int value="0" label="FALLBACK_NONE">SSL version fallback did not occur.</int> <int value="1" label="FALLBACK_SSL3">Fell back on SSL 3.0.</int> <int value="2" label="FALLBACK_TLS1">Fell back on TLS 1.0.</int> <int value="3" label="FALLBACK_TLS1_1">Fell back on TLS 1.1.</int> </enum> -<enum name="FaultTolerantHeap" type="int"> +<enum name="FaultTolerantHeap"> <int value="0" label="FTH_OFF">FTH is completely off.</int> <int value="1" label="FTH_HKLM">FTH is enabled in HKLM.</int> <int value="2" label="FTH_HKCU">FTH is enabled in HKCU.</int> @@ -13371,7 +13377,7 @@ </int> </enum> -<enum name="FaviconDownloadStatus" type="int"> +<enum name="FaviconDownloadStatus"> <int value="0" label="SUCCEEDED">Download succeeded.</int> <int value="1" label="FAILED">Download failed.</int> <int value="2" label="SKIPPED"> @@ -13382,7 +13388,7 @@ </int> </enum> -<enum name="FaviconFetchResult" type="int"> +<enum name="FaviconFetchResult"> <int value="0" label="SUCCESS_CACHED"> Success - favicon found in local cache </int> @@ -13392,7 +13398,7 @@ <int value="2" label="FAILURE">Failure - favicon not available</int> </enum> -<enum name="FeatureObserver" type="int"> +<enum name="FeatureObserver"> <!-- Generated from third_party/WebKit/public/platform/WebFeature.h --> <int value="0" label="OBSOLETE_PageDestruction"/> @@ -15468,7 +15474,7 @@ <int value="2026" label="DocumentDomainSetWithDefaultPort"/> </enum> -<enum name="FeedbackSource" type="int"> +<enum name="FeedbackSource"> <int value="0" label="Arc App"/> <int value="1" label="Ash"/> <int value="2" label="Browser Command"/> @@ -15479,7 +15485,7 @@ <int value="7" label="Supervised User Interstitial"/> </enum> -<enum name="FetchRequestMode" type="int"> +<enum name="FetchRequestMode"> <int value="0" label="SameOrigin"/> <int value="1" label="NoCORS"/> <int value="2" label="CORS"/> @@ -15487,7 +15493,7 @@ <int value="4" label="Navigate"/> </enum> -<enum name="FFmpegCodecHashes" type="int"> +<enum name="FFmpegCodecHashes"> <int value="-2140893972" label="bfi"/> <int value="-2126016986" label="vp3"/> <int value="-2112225664" label="pcm_s32be"/> @@ -15900,7 +15906,7 @@ <int value="2146164868" label="v410"/> </enum> -<enum name="FFmpegCodecs" type="int"> +<enum name="FFmpegCodecs"> <obsolete> deprecated Sep 15 2015 in favor of FFmpegCodecHashes </obsolete> @@ -16275,13 +16281,13 @@ <int value="1950507339" label="TAK"/> </enum> -<enum name="FFmpegColorRanges" type="int"> +<enum name="FFmpegColorRanges"> <int value="0" label="UNSPECIFIED"/> <int value="1" label="MPEG"/> <int value="2" label="JPEG"/> </enum> -<enum name="FileDialogType" type="int"> +<enum name="FileDialogType"> <int value="0" label="Select folder"/> <int value="1" label="Upload folder"/> <int value="2" label="Save as file"/> @@ -16291,12 +16297,12 @@ <int value="6" label="Error"/> </enum> -<enum name="FileManagerQuickViewWayToOpen" type="int"> +<enum name="FileManagerQuickViewWayToOpen"> <int value="0" label="Context menu"/> <int value="1" label="Space key"/> </enum> -<enum name="FileManagerRootType" type="int"> +<enum name="FileManagerRootType"> <int value="0" label="DOWNLOADS"/> <int value="1" label="ARCHIVE"/> <int value="2" label="REMOVABLE"/> @@ -16312,7 +16318,7 @@ <int value="12" label="MEDIA_VIEW"/> </enum> -<enum name="FileManagerVolumeType" type="int"> +<enum name="FileManagerVolumeType"> <int value="0" label="Google Drive"/> <int value="1" label="Download Folder"/> <int value="2" label="Removable Disk"/> @@ -16322,7 +16328,7 @@ <int value="6" label="Media View"/> </enum> -<enum name="FileMetricsProviderAccessResult" type="int"> +<enum name="FileMetricsProviderAccessResult"> <int value="0" label="File was mapped."/> <int value="1" label="File doesn't exist."/> <int value="2" label="File not modified."/> @@ -16333,7 +16339,7 @@ <int value="7" label="File contents internally deleted."/> </enum> -<enum name="FileMetricsProviderEmbeddedProfileResult" type="int"> +<enum name="FileMetricsProviderEmbeddedProfileResult"> <int value="0" label="File was accessed."/> <int value="1" label="File had embedded profile."/> <int value="2" @@ -16342,21 +16348,21 @@ label="File was dropped because no embedded profile was found."/> </enum> -<enum name="FileReaderSyncWorkerType" type="int"> +<enum name="FileReaderSyncWorkerType"> <int value="0" label="Other"/> <int value="1" label="Dedicated Worker"/> <int value="2" label="Shared Worker"/> <int value="3" label="Service Worker"/> </enum> -<enum name="FileSystemDatabaseInitResult" type="int"> +<enum name="FileSystemDatabaseInitResult"> <int value="0" label="OK"/> <int value="1" label="Corruption"/> <int value="2" label="IO Error"/> <int value="3" label="Unknown Error"/> </enum> -<enum name="FileSystemErrors" type="int"> +<enum name="FileSystemErrors"> <int value="0" label="OK"/> <int value="1" label="Incognito"/> <int value="2" label="Invalid Schema"/> @@ -16365,7 +16371,7 @@ <int value="5" label="Unknown Error"/> </enum> -<enum name="FileType" type="int"> +<enum name="FileType"> <int value="0" label="other"/> <int value="1" label=".doc"/> <int value="2" label=".docx"/> @@ -16389,20 +16395,20 @@ <int value="20" label=".log"/> </enum> -<enum name="FirstMeaningfulPaintOrdering" type="int"> +<enum name="FirstMeaningfulPaintOrdering"> <int value="0" label="FMP 0-quiet < FMP 2-quiet"/> <int value="1" label="FMP 0-quiet > FMP 2-quiet"/> <int value="2" label="FMP 0-quiet = FMP 2-quiet"/> </enum> -<enum name="FirstMeaningfulPaintSignalStatus" type="int"> +<enum name="FirstMeaningfulPaintSignalStatus"> <int value="0" label="No input, network active"/> <int value="1" label="Had input, network active"/> <int value="2" label="No input, network stable"/> <int value="3" label="Had input, network stable"/> </enum> -<enum name="FirstMeaningfulPaintStatus" type="int"> +<enum name="FirstMeaningfulPaintStatus"> <int value="0" label="Recorded successfully"/> <int value="1" label="The page was backgrounded"/> <int value="2" label="User left the page before network stable"/> @@ -16410,7 +16416,7 @@ <int value="4" label="User left the page before first contentful paint"/> </enum> -<enum name="FlashNavigateUsageType" type="int"> +<enum name="FlashNavigateUsageType"> <int value="0" label="Rejected because of Authorization header."/> <int value="1" label="Rejected because of Cache-Control header."/> <int value="2" label="Rejected because of Content-Encoding header."/> @@ -16430,14 +16436,14 @@ <int value="15" label="The total number of navigate requests."/> </enum> -<enum name="FlashTinyContentSize" type="int"> +<enum name="FlashTinyContentSize"> <int value="0" label="1x1 or smaller"/> <int value="1" label="5x5 or smaller"/> <int value="2" label="10x10 or smaller"/> <int value="3" label="Large"/> </enum> -<enum name="FlashUsage" type="int"> +<enum name="FlashUsage"> <int value="0" label="Started NPAPI Flash at least once"> Number of browser processes that have started at least one NPAPI Flash process during their lifetime. @@ -16451,7 +16457,7 @@ </int> </enum> -<enum name="FontDisplayValue" type="int"> +<enum name="FontDisplayValue"> <int value="0" label="auto"/> <int value="1" label="block"/> <int value="2" label="swap"/> @@ -16459,7 +16465,7 @@ <int value="4" label="optional"/> </enum> -<enum name="FormDataDeserializationStatus" type="int"> +<enum name="FormDataDeserializationStatus"> <int value="0" label="Login database success"/> <int value="1" label="Login database failure"/> <int value="2" label="Libsecret success"/> @@ -16468,14 +16474,14 @@ <int value="5" label="GNOME failure"/> </enum> -<enum name="FramebustPermissions" type="int"> +<enum name="FramebustPermissions"> <int value="0" label="Only permitted for framebusting, no user gesture"/> <int value="1" label="Only permitted for framebusting, user gesture"/> <int value="2" label="Allowed navigation, no user gesture"/> <int value="3" label="Allowed navigation, user gesture"/> </enum> -<enum name="FtpDataConnectionError" type="int"> +<enum name="FtpDataConnectionError"> <int value="0" label="Data connection successful"/> <int value="1" label="Local firewall blocked the connection"/> <int value="2" label="Connection timed out"/> @@ -16486,7 +16492,7 @@ <int value="20" label="Other kind of error"/> </enum> -<enum name="FtpServerType" type="int"> +<enum name="FtpServerType"> <obsolete> Deprecated 2012-11-13. No longer generated. </obsolete> @@ -16512,7 +16518,7 @@ </int> </enum> -<enum name="FtpServerType2" type="int"> +<enum name="FtpServerType2"> <summary> FTP server type as defined in net/ftp/ftp_server_type_histograms.h </summary> @@ -16526,7 +16532,7 @@ <int value="5" label="OS/2">Obsolete, no longer detected or supported.</int> </enum> -<enum name="GaiaSessionRestoreOutcome" type="int"> +<enum name="GaiaSessionRestoreOutcome"> <int value="0" label="Undefined"/> <int value="1" label="Success"/> <int value="2" label="OAuth2 tokens cannot be fetched"/> @@ -16538,7 +16544,7 @@ <int value="8" label="Overflow"/> </enum> -<enum name="Gamma" type="int"> +<enum name="Gamma"> <int value="0" label="GammaLinear"/> <int value="1" label="GammaSRGB"/> <int value="2" label="Gamma2Dot2"/> @@ -16552,7 +16558,7 @@ <int value="10" label="GammaNamed"/> </enum> -<enum name="Gamut" type="int"> +<enum name="Gamut"> <int value="0" label="GamutUnknown"/> <int value="1" label="GamutLessThanNTSC"/> <int value="2" label="GamutNTSC"/> @@ -16566,7 +16572,7 @@ <int value="10" label="GamutUltraWide"/> </enum> -<enum name="GarbageCollectionReason" type="int"> +<enum name="GarbageCollectionReason"> <int value="0" label="kUnknown"/> <int value="1" label="kAllocationFailure"/> <int value="2" label="kAllocationLimit"/> @@ -16591,7 +16597,7 @@ <int value="21" label="kTesting"/> </enum> -<enum name="GATTCharacteristicHash" type="int"> +<enum name="GATTCharacteristicHash"> <!-- Hash values can be produced using tool: bluetooth_metrics_hash --> <int value="1615384" label="alert_notification_control_point"/> @@ -16955,7 +16961,7 @@ <int value="2140490935" label="gatt.service_changed"/> </enum> -<enum name="GATTDescriptorHash" type="int"> +<enum name="GATTDescriptorHash"> <!-- Hash values can be produced using tool: bluetooth_metrics_hash --> <int value="34360078" @@ -16999,7 +17005,7 @@ 00002900-0000-1000-8000-00805f9b34fb"/> </enum> -<enum name="GATTServiceHash" type="int"> +<enum name="GATTServiceHash"> <!-- Hash values can be produced using tool: bluetooth_metrics_hash --> <int value="7464675" label="pulse_oximeter"/> @@ -17366,7 +17372,7 @@ <int value="2136716957" label="fe69"/> </enum> -<enum name="GCMCheckinRequestStatus" type="int"> +<enum name="GCMCheckinRequestStatus"> <int value="0" label="Success"/> <int value="1" label="URL fetching failed"/> <int value="2" label="HTTP bad request"/> @@ -17376,7 +17382,7 @@ <int value="6" label="Zero ID or token"/> </enum> -<enum name="GCMClientResult" type="int"> +<enum name="GCMClientResult"> <int value="0" label="Success"/> <int value="1" label="Invalid parameter"/> <int value="2" label="GCM disabled"/> @@ -17387,7 +17393,7 @@ <int value="7" label="Unknown error"/> </enum> -<enum name="GCMConnectionResetReason" type="int"> +<enum name="GCMConnectionResetReason"> <int value="0" label="Login failure"/> <int value="1" label="Close command"/> <int value="2" label="Heartbeat failure"/> @@ -17396,7 +17402,7 @@ <int value="5" label="New heartbeat interval"/> </enum> -<enum name="GCMDecryptionResult" type="int"> +<enum name="GCMDecryptionResult"> <int value="0" label="Success (message unencrypted)"/> <int value="1" label="Success (message decrypted per draft 03)"/> <int value="2" label="Failure (invalid Encryption HTTP header)"/> @@ -17408,26 +17414,26 @@ <int value="8" label="Success (message decrypted per draft 08)"/> </enum> -<enum name="GCMEndpoints" type="int"> +<enum name="GCMEndpoints"> <int value="0" label="mtalk.google.com:5228"/> <int value="1" label="mtalk.google.com:443"/> </enum> -<enum name="GCMInvalidationsIncomingMessageStatus" type="int"> +<enum name="GCMInvalidationsIncomingMessageStatus"> <int value="0" label="Success"/> <int value="1" label="GCM message's content missing or empty"/> <int value="2" label="Base64Decode failed"/> <int value="3" label="Parsing protobuf failed"/> </enum> -<enum name="GCMInvalidationsOutgoingMessageStatus" type="int"> +<enum name="GCMInvalidationsOutgoingMessageStatus"> <int value="0" label="Success"/> <int value="1" label="Message was discarded"/> <int value="2" label="Access token request failed"/> <int value="3" label="HTTP Post failed"/> </enum> -<enum name="GCMLoadStatus" type="int"> +<enum name="GCMLoadStatus"> <int value="0" label="Success"/> <int value="1" label="Reloading open store"/> <int value="2" label="Store open failed"/> @@ -17444,7 +17450,7 @@ <int value="13" label="Store does not exist"/> </enum> -<enum name="GCMOutgoingMessageTTLCategory" type="int"> +<enum name="GCMOutgoingMessageTTLCategory"> <int value="0" label="Zero"/> <int value="1" label="Less than or equal to 1 minute"/> <int value="2" label="Less than or equal to 1 hour"/> @@ -17454,7 +17460,7 @@ <int value="6" label="Default or maximium time"/> </enum> -<enum name="GcmReceiverStatus" type="int"> +<enum name="GcmReceiverStatus"> <obsolete> Deprecated as of 01/2016. The error has been fixed by GCM. (crbug/580367) </obsolete> @@ -17462,7 +17468,7 @@ <int value="1" label="ERROR_SECURITY_EXCEPTION"/> </enum> -<enum name="GCMRegistrationRequestStatus" type="int"> +<enum name="GCMRegistrationRequestStatus"> <int value="0" label="Success (this is not logged currently)"/> <int value="1" label="Invalid parameters"/> <int value="2" label="Invalid sender"/> @@ -17479,12 +17485,12 @@ <int value="13" label="Device has too many registrations"/> </enum> -<enum name="GCMResetStoreError" type="int"> +<enum name="GCMResetStoreError"> <int value="0" label="Destroying store failed"/> <int value="1" label="Infinite store reset"/> </enum> -<enum name="GCMSendMessageStatus" type="int"> +<enum name="GCMSendMessageStatus"> <int value="0" label="Message queued"/> <int value="1" label="Message sent to the server, ACK received"/> <int value="2" label="Message not saved, exceeded app queue size"/> @@ -17494,7 +17500,7 @@ <int value="6" label="Message TTL exceeded"/> </enum> -<enum name="GCMUnregistrationRequestStatus" type="int"> +<enum name="GCMUnregistrationRequestStatus"> <int value="0" label="Success"/> <int value="1" label="URL fetching failed"/> <int value="2" label="No response body"/> @@ -17509,14 +17515,14 @@ <int value="11" label="Device registration error"/> </enum> -<enum name="GCMUpstreamMessageStatus" type="int"> +<enum name="GCMUpstreamMessageStatus"> <int value="0" label="Success"/> <int value="1" label="Message size limit exceeded"/> <int value="2" label="Access token request failed"/> <int value="3" label="Send request failed"/> </enum> -<enum name="GCReason" type="int"> +<enum name="GCReason"> <int value="0" label="Idle GC"/> <int value="1" label="Precise GC"/> <int value="2" label="Conservative GC"/> @@ -17525,13 +17531,13 @@ <int value="5" label="Page navigation GC"/> </enum> -<enum name="GDataAuthResult" type="int"> +<enum name="GDataAuthResult"> <int value="0" label="FAILURE"/> <int value="1" label="SUCCESS"/> <int value="2" label="NO_CONNECTION"/> </enum> -<enum name="GDataEntryKind" type="int"> +<enum name="GDataEntryKind"> <obsolete> Deprecated 9/2012, and replaced by DriveEntryKind </obsolete> @@ -17549,13 +17555,13 @@ <int value="32770" label="PDF"/> </enum> -<enum name="GeolocationDisclosureResult" type="int"> +<enum name="GeolocationDisclosureResult"> <int value="0" label="Ignored"/> <int value="1" label="Settings clicked"/> <int value="2" label="Dismissed"/> </enum> -<enum name="GeolocationHeaderPermissionState" type="int"> +<enum name="GeolocationHeaderPermissionState"> <int value="0" label="Location mode unknown"/> <int value="1" label="High acc., app allowed, domain allowed, location sent"/> <int value="2" @@ -17611,7 +17617,7 @@ <int value="44" label="Not using HTTPS"/> </enum> -<enum name="GeolocationInfoBarDelegateAndroidEvent" type="int"> +<enum name="GeolocationInfoBarDelegateAndroidEvent"> <obsolete> Deprecated 9/2014, and replaced by PermissionAction. </obsolete> @@ -17622,7 +17628,7 @@ <int value="1" label="User opened geolocation settings"/> </enum> -<enum name="GeolocationInfoBarDelegateEvent" type="int"> +<enum name="GeolocationInfoBarDelegateEvent"> <obsolete> Deprecated 9/2014, and replaced by PermissionAction. </obsolete> @@ -17634,21 +17640,21 @@ <int value="5" label="User ignored the bar"/> </enum> -<enum name="GeolocationSettingsDialogBackOff" type="int"> +<enum name="GeolocationSettingsDialogBackOff"> <int value="0" label="No backoff"/> <int value="1" label="One week"/> <int value="2" label="One month"/> <int value="3" label="Three months"/> </enum> -<enum name="GeopositionErrorCode" type="int"> +<enum name="GeopositionErrorCode"> <int value="0" label="There was no error"/> <int value="1" label="User denied use of geolocation"/> <int value="2" label="Geoposition could not be determined"/> <int value="3" label="Timeout"/> </enum> -<enum name="GestureActionType" type="int"> +<enum name="GestureActionType"> <int value="0" label="Unknown"/> <int value="1" label="Omnibox pinch"/> <int value="2" label="Omnibox scroll"/> @@ -17672,20 +17678,20 @@ <int value="20" label="Window resized double tap"/> </enum> -<enum name="GestureMergeState" type="int"> +<enum name="GestureMergeState"> <int value="0" label="Neither token had a gesture"/> <int value="1" label="Only the old token had a gesture"/> <int value="2" label="Only the new token had a gesture"/> <int value="3" label="Both tokens had a gesture"/> </enum> -<enum name="GesturePredictionResult" type="int"> +<enum name="GesturePredictionResult"> <int value="0" label="Gesture occured and was predicted"/> <int value="1" label="Gesture occured but was not predicted"/> <int value="2" label="Gesture predicted but didn't occur"/> </enum> -<enum name="GetOutputDeviceInfoCacheHit" type="int"> +<enum name="GetOutputDeviceInfoCacheHit"> <int value="0" label="Miss: no cached sink found"> Output parmeters for a device are requested, and there is no corresponding sink cached; new sink is created and cached. @@ -17700,7 +17706,7 @@ </int> </enum> -<enum name="GetPerfDataOutcome" type="int"> +<enum name="GetPerfDataOutcome"> <int value="0" label="Success."> Perf data was collected, parsed and attached to the UMA protobuf successfully. @@ -17733,7 +17739,7 @@ </int> </enum> -<enum name="GetUserDataTempDirResult" type="int"> +<enum name="GetUserDataTempDirResult"> <int value="0" label="SUCCESS"/> <int value="1" label="CANT_GET_PARENT_PATH"/> <int value="2" label="CANT_GET_UDT_PATH"/> @@ -17743,7 +17749,7 @@ <int value="6" label="UNSET"/> </enum> -<enum name="GLError" type="int"> +<enum name="GLError"> <int value="0" label="0x0000 - GL_NO_ERROR"/> <int value="1280" label="0x0500 - GL_INVALID_ENUM"/> <int value="1281" label="0x0501 - GL_INVALID_VALUE"/> @@ -17752,12 +17758,12 @@ <int value="1286" label="0x0506 - GL_INVALID_FRAMEBUFFER_OPERATION"/> </enum> -<enum name="GoogleCaptchaEvent" type="int"> +<enum name="GoogleCaptchaEvent"> <int value="0" label="Google CAPTCHA shown"/> <int value="1" label="Google CAPTCHA solved"/> </enum> -<enum name="GoogleNowCardTypeId" type="int"> +<enum name="GoogleNowCardTypeId"> <summary> Represents a card type ID. See cardTypeId in chrome/browser/resources/google_now/background.js. @@ -17774,7 +17780,7 @@ <int value="43" label="Reminder"/> </enum> -<enum name="GoogleNowEvent" type="int"> +<enum name="GoogleNowEvent"> <summary> Events in Google Now component extension. See GoogleNowEvent in chrome/browser/resources/google_now/background.js. @@ -17795,7 +17801,7 @@ <int value="13" label="GOOGLE_NOW_DISABLED"/> </enum> -<enum name="GooglePlayServicesConnectionResult" type="int"> +<enum name="GooglePlayServicesConnectionResult"> <summary> Results of attempting a connection to Google Play Services. See Javadoc for com.google.android.gms.common.ConnectionResult at @@ -17823,7 +17829,7 @@ <int value="1500" label="DRIVE_EXTERNAL_STORAGE_REQUIRED"/> </enum> -<enum name="GooglePlayServicesErrorHandlerAction" type="int"> +<enum name="GooglePlayServicesErrorHandlerAction"> <summary> Types of action taken in response to Google Play Services user-recoverable errors. See subclasses of UserRecoverableErrorHandler in @@ -17836,7 +17842,7 @@ <int value="3" label="IGNORED_AS_REDUNDANT"/> </enum> -<enum name="GoogleServiceAuthError" type="int"> +<enum name="GoogleServiceAuthError"> <int value="0" label="NONE"/> <int value="1" label="INVALID_GAIA_CREDENTIALS"/> <int value="2" label="USER_NOT_SIGNED_UP"/> @@ -17853,12 +17859,12 @@ <int value="13" label="WEB_LOGIN_REQUIRED"/> </enum> -<enum name="GoogleUpdateAfterItemClickedActions" type="int"> +<enum name="GoogleUpdateAfterItemClickedActions"> <int value="0" label="Updated"/> <int value="1" label="Not updated"/> </enum> -<enum name="GoogleUpdateErrorCode" type="int"> +<enum name="GoogleUpdateErrorCode"> <int value="0" label="GOOGLE_UPDATE_NO_ERROR"/> <int value="1" label="CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY"/> <int value="2" label="GOOGLE_UPDATE_JOB_SERVER_CREATION_FAILED"/> @@ -17871,20 +17877,20 @@ <int value="9" label="GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY"/> </enum> -<enum name="GoogleUpdateInfoBarActions" type="int"> +<enum name="GoogleUpdateInfoBarActions"> <int value="0" label="Clicked close"/> <int value="1" label="Clicked to update appears successful"/> <int value="2" label="Clicked to update but failed"/> <int value="3" label="InfoBar dismissed implicitly (no interaction)"/> </enum> -<enum name="GoogleUpdateMenuItemActions" type="int"> +<enum name="GoogleUpdateMenuItemActions"> <int value="0" label="Not clicked"/> <int value="1" label="Clicked, intent launched"/> <int value="2" label="Clicked, intent failed"/> </enum> -<enum name="GoogleUpdateUpgradeStatus" type="int"> +<enum name="GoogleUpdateUpgradeStatus"> <int value="0" label="UPGRADE_STARTED"/> <int value="1" label="UPGRADE_CHECK_STARTED"/> <int value="2" label="UPGRADE_IS_AVAILABLE"/> @@ -17893,7 +17899,7 @@ <int value="5" label="UPGRADE_ERROR"/> </enum> -<enum name="GPUBlacklistFeatureTestResults" type="int"> +<enum name="GPUBlacklistFeatureTestResults"> <summary> Results of testing against a GPU feature being allowed/blacklisted/disabled. </summary> @@ -17902,7 +17908,7 @@ <int value="2" label="User-disabled"/> </enum> -<enum name="GPUBlacklistFeatureTestResultsWin" type="int"> +<enum name="GPUBlacklistFeatureTestResultsWin"> <summary> Results of testing against a GPU feature being blacklisted or not in various Windows sub-versions. @@ -17917,7 +17923,7 @@ <int value="7" label="Blacklisted Win7"/> </enum> -<enum name="GPUBlacklistFeatureTestResultsWindows" type="int"> +<enum name="GPUBlacklistFeatureTestResultsWindows"> <summary> Results of testing against a GPU feature being allowed/blacklisted/disabled in various Windows sub-versions. @@ -17939,7 +17945,7 @@ <int value="14" label="User-disabled Win8"/> </enum> -<enum name="GPUBlacklistTestResultPerEntry" type="int"> +<enum name="GPUBlacklistTestResultPerEntry"> <summary>Results of testing against the GPU blacklist entries.</summary> <int value="0" label="TotalCount"/> <int value="1" label="Mac/ATI/Radeon X1900"/> @@ -18023,7 +18029,7 @@ <int value="75" label="Win/AMD_switchable/Texture_sharing"/> </enum> -<enum name="GpuDriverBugWorkaroundEntry" type="int"> +<enum name="GpuDriverBugWorkaroundEntry"> <!-- Generated from gpu/config/gpu_driver_bug_list.json --> <int value="0" @@ -18448,14 +18454,14 @@ AMD"/> </enum> -<enum name="GpuImageDecodeState" type="int"> +<enum name="GpuImageDecodeState"> <int value="0" label="Wasted, once"/> <int value="1" label="Used, once"/> <int value="2" label="Wasted, relocked"/> <int value="3" label="Used, relocked"/> </enum> -<enum name="GPUProcessExitCode" type="int"> +<enum name="GPUProcessExitCode"> <summary> The exit code returned by the GPU process when it terminated. These match the enumeration in result_codes.h. @@ -18467,7 +18473,7 @@ <int value="4" label="DeadOnArrival"/> </enum> -<enum name="GPUProcessLaunchCauses" type="int"> +<enum name="GPUProcessLaunchCauses"> <summary> Causes for the GPU Process to be launched. From: content/common/gpu/gpu_process_launch_causes.h @@ -18530,7 +18536,7 @@ </int> </enum> -<enum name="GPUProcessLifetimeEvent" type="int"> +<enum name="GPUProcessLifetimeEvent"> <summary> Lifetime events of the GPU Process, as defined in chrome/browser/gpu_process_host.cc. DiedFourth should never happen as it is @@ -18544,12 +18550,12 @@ <int value="4" label="DiedFourth"/> </enum> -<enum name="GPUProcessType" type="int"> +<enum name="GPUProcessType"> <int value="0" label="Hardware"/> <int value="1" label="Software"/> </enum> -<enum name="GPUsetIsAcceleratedCompositingActive" type="int"> +<enum name="GPUsetIsAcceleratedCompositingActive"> <summary> Combinations of input parameter active and previous active state set in third_party/WebKit/WebKit/chromium/src/ChromiumBridge.cpp @@ -18560,14 +18566,14 @@ <int value="3" label="active, was active"/> </enum> -<enum name="GPUThreeDAPIInfoBarDismissal" type="int"> +<enum name="GPUThreeDAPIInfoBarDismissal"> <summary>Results of user actions when a 3D API info bar is raised.</summary> <int value="0" label="Ignored"/> <int value="1" label="Reloaded"/> <int value="2" label="Closed without action"/> </enum> -<enum name="GPUWebGraphicsContext3D_Init_CanLoseContext" type="int"> +<enum name="GPUWebGraphicsContext3D_Init_CanLoseContext"> <summary> Combinations of context loss variables from chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc @@ -18586,38 +18592,38 @@ gpu_info.can_lose_context=True"/> </enum> -<enum name="GsaAccountChangeNotificationSource" type="int"> +<enum name="GsaAccountChangeNotificationSource"> <int value="0" label="Service"/> <int value="1" label="Broadcast"/> </enum> -<enum name="GzipEncodingFixupResult" type="int"> +<enum name="GzipEncodingFixupResult"> <int value="0" label="Gzip encoding left as-is"/> <int value="1" label="MIME type indicated GZIP content"/> <int value="2" label="Explicit download with GZIP filename extension"/> <int value="3" label="Unhandled MIME type with a GZIP filename extension"/> </enum> -<enum name="HadFormInteraction" type="int"> +<enum name="HadFormInteraction"> <int value="0" label="No form interaction"/> <int value="1" label="Observed form interaction"/> </enum> -<enum name="HandleStateType" type="int"> +<enum name="HandleStateType"> <int value="0" label="Launch"/> <int value="1" label="Checked launch"/> <int value="2" label="Dont launch"/> <int value="3" label="Checked dont launch"/> </enum> -<enum name="HIDContinueScenarioType" type="int"> +<enum name="HIDContinueScenarioType"> <summary>Possible detected devices combination on leaving dialog</summary> <int value="0" label="Pointing device only detected."/> <int value="1" label="Keyboard device only detected."/> <int value="2" label="Both devices, pointing and keyboard, detected."/> </enum> -<enum name="HistogramActivityReport" type="int"> +<enum name="HistogramActivityReport"> <int value="0" label="Reports created"/> <int value="1" label="Histograms created"/> <int value="2" label="Histograms found by look-up"/> @@ -18631,14 +18637,14 @@ <int value="10" label="Persistent histograms created"/> </enum> -<enum name="HistogramNameHash" type="int"> +<enum name="HistogramNameHash"> <summary> These numbers are the lower 32 bits of the hash of the metric name. </summary> <int value="0" label="Missing hash value"/> </enum> -<enum name="HistoryFaviconsRecoveryEnum" type="int"> +<enum name="HistoryFaviconsRecoveryEnum"> <summary>Error states noted in thumbnail_database.cc recovery code.</summary> <obsolete> History.FaviconsRecovery no longer tracked as of March 2017. @@ -18727,7 +18733,7 @@ </int> </enum> -<enum name="HistoryPageView" type="int"> +<enum name="HistoryPageView"> <int value="0" label="History"/> <int value="1" label="Grouped Week (Obsolete Feb. 2017)"/> <int value="2" label="Grouped Month (Obsolete Feb. 2017)"/> @@ -18735,7 +18741,7 @@ <int value="4" label="Signin Promo"/> </enum> -<enum name="HistoryTopSitesRecoveryEnum" type="int"> +<enum name="HistoryTopSitesRecoveryEnum"> <summary>Error states noted in top_sites_database.cc recovery code.</summary> <int value="0" label="RECOVERY_EVENT_RECOVERED">Successful recovery.</int> <int value="1" label="RECOVERY_EVENT_DEPRECATED"> @@ -18776,26 +18782,26 @@ </int> </enum> -<enum name="HomedirEncryptionType" type="int"> +<enum name="HomedirEncryptionType"> <int value="1" label="Ecryptfs"/> <int value="2" label="Ext4 Dir Encryption"/> </enum> -<enum name="HotwordAvailability" type="int"> +<enum name="HotwordAvailability"> <int value="0" label="Unavailable -- reason may be unknown"/> <int value="1" label="Available"/> <int value="2" label="Pending download"/> <int value="3" label="Disabled"/> </enum> -<enum name="HotwordError" type="int"> +<enum name="HotwordError"> <int value="0" label="No error"/> <int value="1" label="Generic error"/> <int value="2" label="NaCl error"/> <int value="3" label="Microphone error"/> </enum> -<enum name="HotwordMediaStreamResult" type="int"> +<enum name="HotwordMediaStreamResult"> <int value="0" label="Success"/> <int value="1" label="Unknown error"/> <int value="2" label="NotSupportedError"/> @@ -18811,7 +18817,7 @@ <int value="12" label="InvalidSecurityOriginError"/> </enum> -<enum name="HotwordNaClMessageTimeout" type="int"> +<enum name="HotwordNaClMessageTimeout"> <int value="0" label="REQUEST_MODEL"/> <int value="1" label="MODEL_LOADED"/> <int value="2" label="READY_FOR_AUDIO"/> @@ -18820,28 +18826,28 @@ <int value="5" label="MS_CONFIGURED"/> </enum> -<enum name="HotwordNaClPluginLoadResult" type="int"> +<enum name="HotwordNaClPluginLoadResult"> <int value="0" label="Success"/> <int value="1" label="Unknown error"/> <int value="2" label="Module crash"/> <int value="3" label="Module not found"/> </enum> -<enum name="HotwordPrefState" type="int"> +<enum name="HotwordPrefState"> <int value="0" label="Preference not set"/> <int value="1" label="'Classic' hotwording enabled"/> <int value="2" label="Hotwording disabled"/> <int value="3" label="Always-on hotwording enabled"/> </enum> -<enum name="HotwordTriggerSource" type="int"> +<enum name="HotwordTriggerSource"> <int value="0" label="Launcher (except when always-on is enabled)"/> <int value="1" label="NTP or google.com"/> <int value="2" label="Always-On"/> <int value="3" label="Training Mode"/> </enum> -<enum name="Hresult" type="int"> +<enum name="Hresult"> <int value="-2147467263" label="E_NOTIMPL"/> <int value="-2147467262" label="E_NOINTERFACE"/> <int value="-2147467261" label="E_POINTER"/> @@ -18903,7 +18909,7 @@ <int value="-1606219747" label="GOOPDATE_E_APP_USING_EXTERNAL_UPDATER"/> </enum> -<enum name="HttpAuthCount" type="int"> +<enum name="HttpAuthCount"> <int value="0" label="Basic Start"/> <int value="1" label="Basic Reject"/> <int value="2" label="Digest Start"/> @@ -18914,7 +18920,7 @@ <int value="7" label="Negotiate Reject"/> </enum> -<enum name="HttpAuthPromptType" type="int"> +<enum name="HttpAuthPromptType"> <int value="0" label="Main frame with interstitial"> Auth prompt displayed over a blank interstitial </int> @@ -18929,14 +18935,14 @@ </int> </enum> -<enum name="HttpAuthResource" type="int"> +<enum name="HttpAuthResource"> <int value="0" label="Top Page Allowed"/> <int value="1" label="Same-domain Sub-resource Allowed"/> <int value="2" label="Cross-domain Sub-resource Blocked"/> <int value="3" label="Cross-domain Sub-resource Allowed"/> </enum> -<enum name="HttpAuthTarget" type="int"> +<enum name="HttpAuthTarget"> <int value="0" label="Basic Proxy"/> <int value="1" label="Basic Secure Proxy"/> <int value="2" label="Basic Server"/> @@ -18955,7 +18961,7 @@ <int value="15" label="Negotiate Secure Server"/> </enum> -<enum name="HttpCachePattern" type="int"> +<enum name="HttpCachePattern"> <int value="0" label="Undefined"/> <int value="1" label="Not Covered"/> <int value="2" label="Not Cached"/> @@ -18965,7 +18971,7 @@ <int value="6" label="CantConditionalize"/> </enum> -<enum name="HttpCacheValidationCause" type="int"> +<enum name="HttpCacheValidationCause"> <int value="0" label="Undefined"/> <int value="1" label="Vary Mismatch"/> <int value="2" label="Validate Flag"/> @@ -18973,7 +18979,7 @@ <int value="4" label="Zero Freshness"/> </enum> -<enum name="HttpHeaderParserEvent" type="int"> +<enum name="HttpHeaderParserEvent"> <int value="0" label="PARSER_INVOKED"/> <int value="1" label="HTTP_09_RESPONSE"/> <int value="2" label="ALLOWED_TRUNCATED_HEADERS"/> @@ -18984,7 +18990,7 @@ <int value="7" label="HEADER_HTTP_09_ON_REUSED_SOCKET"/> </enum> -<enum name="HttpPasswordMigrationMode" type="int"> +<enum name="HttpPasswordMigrationMode"> <int value="0" label="Moved"> HTTP credentials were moved during migration to HTTPS </int> @@ -18993,7 +18999,7 @@ </int> </enum> -<enum name="HttpPipelineStatus" type="int"> +<enum name="HttpPipelineStatus"> <int value="0" label="Success"/> <int value="1" label="Redirected"/> <int value="2" label="Certificate error"/> @@ -19006,7 +19012,7 @@ <int value="9" label="Corrupt stats response"/> </enum> -<enum name="HttpResponseCode" type="int"> +<enum name="HttpResponseCode"> <int value="100" label="100: Continue"/> <int value="101" label="101: Switching Protocols"/> <int value="200" label="200: OK"/> @@ -19050,7 +19056,7 @@ <int value="505" label="505: HTTP Version Not Supported"/> </enum> -<enum name="HttpServerPropertiesUpdatePrefsLocation" type="int"> +<enum name="HttpServerPropertiesUpdatePrefsLocation"> <int value="0" label="SUPPORTS_SPDY"/> <int value="1" label="HTTP_11_REQUIRED"/> <int value="2" label="SET_ALTERNATIVE_SERVICE"/> @@ -19068,7 +19074,7 @@ <int value="14" label="CLEAR_SERVER_NETWORK_STATS"/> </enum> -<enum name="HttpSocketType" type="int"> +<enum name="HttpSocketType"> <int value="0" label="UNUSED">newly connected socket</int> <int value="1" label="UNUSED_IDLE"> connected unused socket (idle prior to use) @@ -19076,7 +19082,7 @@ <int value="2" label="REUSED_IDLE">previously used (keep-alive?) socket</int> </enum> -<enum name="HttpStatusLineStatus" type="int"> +<enum name="HttpStatusLineStatus"> <int value="0" label="OK">Spec-compliant status line</int> <int value="1" label="EMPTY">Empty status line</int> <int value="2" label="NOT_HTTP">Incorrect protocol name</int> @@ -19105,7 +19111,7 @@ </int> </enum> -<enum name="HttpStreamFactoryJobState" type="int"> +<enum name="HttpStreamFactoryJobState"> <summary> State of HttpStreamFactoryJob. See net::HttpStreamFactoryImpl::Job::State for more details @@ -19128,7 +19134,7 @@ <int value="15" label="NONE"/> </enum> -<enum name="ICCProfileAnalyzeResult" type="int"> +<enum name="ICCProfileAnalyzeResult"> <int value="0" label="Extracted primary matrix and numerical transfer function"/> <int value="1" @@ -19140,7 +19146,7 @@ <int value="5" label="Failed to parse"/> </enum> -<enum name="IceCandidatePairTypes" type="int"> +<enum name="IceCandidatePairTypes"> <int value="0" label="host_host"/> <int value="1" label="host_srflx"/> <int value="2" label="host_relay"/> @@ -19162,7 +19168,7 @@ <int value="18" label="host(public)_host(public)"/> </enum> -<enum name="IceConnectionStates" type="int"> +<enum name="IceConnectionStates"> <int value="0" label="IceConnectionNew"/> <int value="1" label="IceConnectionChecking"/> <int value="2" label="IceConnectionConnected"/> @@ -19172,18 +19178,18 @@ <int value="6" label="IceconnectionClosed"/> </enum> -<enum name="IceRegatheringReason" type="int"> +<enum name="IceRegatheringReason"> <int value="0" label="NetworkChange"/> <int value="1" label="NetworkFailure"/> </enum> -<enum name="IceRestartState" type="int"> +<enum name="IceRestartState"> <int value="0" label="Connecting"/> <int value="1" label="Connected"/> <int value="2" label="Disconnected"/> </enum> -<enum name="IDBContextForcedCloseReason" type="int"> +<enum name="IDBContextForcedCloseReason"> <int value="0" label="DeleteOrigin"> A request was made to delete the data for an origin. </int> @@ -19195,7 +19201,7 @@ </int> </enum> -<enum name="IDBException" type="int"> +<enum name="IDBException"> <int value="0" label="Unknown error"/> <int value="1" label="Constraint error"/> <int value="2" label="Data error"/> @@ -19205,13 +19211,13 @@ <int value="6" label="Timeout error"/> </enum> -<enum name="IDBKeyPathType" type="int"> +<enum name="IDBKeyPathType"> <int value="0" label="None">No key path.</int> <int value="1" label="String">Key path is a string.</int> <int value="2" label="Array">Key path is an array of strings.</int> </enum> -<enum name="IDBKeyType" type="int"> +<enum name="IDBKeyType"> <int value="0" label="Invalid">Invalid key.</int> <int value="1" label="Array">Key is an array.</int> <int value="2" label="Binary">Key is a binary buffer.</int> @@ -19220,7 +19226,7 @@ <int value="5" label="Number">Key is a number.</int> </enum> -<enum name="IDBLevelDBBackingStoreInternalErrorType" type="int"> +<enum name="IDBLevelDBBackingStoreInternalErrorType"> <int value="0" label="IDBLevelDBBackingStoreReadError"> IndexedDB encountered an error attempting to read or decode a value from the leveldb backing store, indicative of corruption or I/O error. Unused as of @@ -19261,7 +19267,7 @@ <int value="27" label="GetBlobInfoForRecord"/> </enum> -<enum name="IDBLevelDBBackingStoreOpenResult" type="int"> +<enum name="IDBLevelDBBackingStoreOpenResult"> <int value="0" label="OpenMemorySuccess"> An in-memory backing store was opened successfully. </int> @@ -19320,7 +19326,7 @@ </int> </enum> -<enum name="IdleSocketFate" type="int"> +<enum name="IdleSocketFate"> <int value="0" label="Reuse: Reused"> Reusing an idle socket that is previously used. </int> @@ -19350,7 +19356,7 @@ </int> </enum> -<enum name="IdleTaskStatus" type="int"> +<enum name="IdleTaskStatus"> <int value="0" label="IdleTaskNotStarted"/> <int value="1" label="IdleTaskStarted"/> <int value="2" label="IdleTaskCompleted"/> @@ -19359,7 +19365,7 @@ <int value="5" label="IdleTaskNotSupported"/> </enum> -<enum name="IMECommitType" type="int"> +<enum name="IMECommitType"> <obsolete> Deprecated 03/2015, and replaced by IMECommitType2. </obsolete> @@ -19381,7 +19387,7 @@ </int> </enum> -<enum name="IMECommitType2" type="int"> +<enum name="IMECommitType2"> <int value="0" label="X -> X(0)"> Types X, commits X as the top suggestion. </int> @@ -19407,13 +19413,13 @@ <int value="8" label="Voice">The commit is triggered by voice input.</int> </enum> -<enum name="IMECorrectionLevel" type="int"> +<enum name="IMECorrectionLevel"> <int value="0" label="Off"/> <int value="1" label="Modest"/> <int value="2" label="Aggressive"/> </enum> -<enum name="IMEGestureTypingEvent" type="int"> +<enum name="IMEGestureTypingEvent"> <int value="0" label="Typed">A word was typed with a gesture.</int> <int value="1" label="Deleted"> A gesture-typed word was deleted after being typed. @@ -19429,7 +19435,7 @@ </int> </enum> -<enum name="ImeMenuButtonType" type="int"> +<enum name="ImeMenuButtonType"> <int value="0" label="Unknown"/> <int value="1" label="Emoji"/> <int value="2" label="Handwriting"/> @@ -19437,7 +19443,7 @@ <int value="4" label="Settings"/> </enum> -<enum name="IMERegisterProxyView" type="int"> +<enum name="IMERegisterProxyView"> <int value="0" label="Success">Success in registering ProxyView to IMM</int> <int value="1" label="Failure">Failure in registering ProxyView to IMM</int> <int value="2" label="DetectionFailure">Failure in detecting the result</int> @@ -19446,12 +19452,12 @@ </int> </enum> -<enum name="IMESwitchType" type="int"> +<enum name="IMESwitchType"> <int value="0" label="By tray menu">IME switches by tray menu</int> <int value="1" label="By accelerator">IME switches by accelerator</int> </enum> -<enum name="IMEVKLayout" type="int"> +<enum name="IMEVKLayout"> <int value="0" label="Compact"/> <int value="1" label="CompactSymbol"/> <int value="2" label="CompactMore"/> @@ -19461,7 +19467,7 @@ <int value="6" label="Emoji"/> </enum> -<enum name="ImportantSitesReason" type="int"> +<enum name="ImportantSitesReason"> <int value="0" label="Engagement"/> <int value="1" label="Durable"/> <int value="2" label="Bookmarks"/> @@ -19469,7 +19475,7 @@ <int value="4" label="Notifications"/> </enum> -<enum name="ImporterType" type="int"> +<enum name="ImporterType"> <int value="0" label="Unknown"/> <int value="1" label="IMPORTER_METRICS_IE">IE (Windows-only)</int> <int value="2" label="IMPORTER_METRICS_FIREFOX2">Firefox 2</int> @@ -19482,7 +19488,7 @@ <int value="7" label="IMPORTER_METRICS_EDGE">Edge (Windows-only)</int> </enum> -<enum name="IncidentType" type="int"> +<enum name="IncidentType"> <int value="1" label="TrackedPreference"/> <int value="2" label="BinaryIntegrity"/> <int value="3" label="BlacklistLoad"/> @@ -19492,7 +19498,7 @@ <int value="7" label="SuspiciousModule"/> </enum> -<enum name="Inconsistencies" type="int"> +<enum name="Inconsistencies"> <int value="1" label="RangeChecksum"/> <int value="2" label="BucketOrder"/> <int value="3" label="RangeChecksum BucketOrder"/> @@ -19506,7 +19512,7 @@ <int value="11" label="CountLow RangeChecksum BucketOrder"/> </enum> -<enum name="IndexedDatabaseMethods" type="int"> +<enum name="IndexedDatabaseMethods"> <int value="0" label="CreateObjectStore()"/> <int value="1" label="DeleteObjectStore()"/> <int value="2" label="Transaction()"/> @@ -19514,7 +19520,7 @@ <int value="4" label="Open()"/> </enum> -<enum name="InfoBarIdentifier" type="int"> +<enum name="InfoBarIdentifier"> <int value="-1" label="INVALID"/> <int value="0" label="TEST_INFOBAR"/> <int value="1" label="APP_BANNER_INFOBAR_DELEGATE_ANDROID"/> @@ -19596,21 +19602,21 @@ <int value="76" label="VR_FEEDBACK_INFOBAR_ANDROID"/> </enum> -<enum name="InfoBarResponse" type="int"> +<enum name="InfoBarResponse"> <int value="0" label="No Response selected"/> <int value="1" label="Save Password"/> <int value="2" label="Never for this site (blacklist / exception)"/> <int value="3" label="InfoBar dismissed by clicking the 'X'"/> </enum> -<enum name="InitialRttEstimateSource" type="int"> +<enum name="InitialRttEstimateSource"> <int value="0" label="Default"/> <int value="1" label="Cached"/> <int value="2" label="2G"/> <int value="3" label="3G"/> </enum> -<enum name="InjectedAdType" type="int"> +<enum name="InjectedAdType"> <int value="0" label="Invalid"/> <int value="1" label="IFrame"/> <int value="2" label="Embed"/> @@ -19618,7 +19624,7 @@ <int value="4" label="Script"/> </enum> -<enum name="InputMethodCategory" type="int"> +<enum name="InputMethodCategory"> <int value="0" label="Unkown"/> <int value="1" label="XKB">XKeyboard</int> <int value="2" label="Chinese"/> @@ -19628,7 +19634,7 @@ <int value="6" label="T13n">Transliteration</int> </enum> -<enum name="InputMethodID" type="int"> +<enum name="InputMethodID"> <int value="109700" label="xkb:am:phonetic:arm"> Armenian Phonetic keyboard </int> @@ -19785,7 +19791,7 @@ <int value="611700" label="ur-t-i0-und">Transliteration Urdu</int> </enum> -<enum name="InputMethodID2" type="int"> +<enum name="InputMethodID2"> <int value="-2082426075" label="xkb:cz:qwerty:cze">Czech QWERTY keyboard</int> <int value="-2039513744" label="xkb:ru::rus">Russian keyboard</int> <int value="-2004968165" label="xkb:gb:dvorak:eng">UK Dvorak keyboard</int> @@ -19980,7 +19986,7 @@ <int value="2121258069" label="xkb:us:dvorak:eng">US Dvorak keyboard</int> </enum> -<enum name="InsecureContentType" type="int"> +<enum name="InsecureContentType"> <int value="0" label="Displayed"/> <int value="1" label="Displayed by *.google.com (deprecated)"/> <int value="2" label="Displayed by www.google.com (deprecated)"/> @@ -20019,7 +20025,7 @@ <int value="35" label="Ran by google.com/intl/ (deprecated)"/> </enum> -<enum name="InstallabilityCheckStatus" type="int"> +<enum name="InstallabilityCheckStatus"> <int value="0" label="Check not started"/> <int value="1" label="Check terminated before it could finish"/> <int value="2" label="Check not complete, site is not a PWA"/> @@ -20028,7 +20034,7 @@ <int value="5" label="Check complete, site is a PWA"/> </enum> -<enum name="InstallStatus" type="int"> +<enum name="InstallStatus"> <int value="0" label="FIRST_INSTALL_SUCCESS"/> <int value="1" label="INSTALL_REPAIRED"/> <int value="2" label="NEW_VERSION_UPDATED"/> @@ -20082,7 +20088,7 @@ <int value="63" label="DELETE_OLD_VERSIONS_TOO_MANY_ATTEMPTS"/> </enum> -<enum name="InstanceIDResult" type="int"> +<enum name="InstanceIDResult"> <int value="0" label="Success"/> <int value="1" label="Invalid parameter"/> <int value="2" label="GCM disabled"/> @@ -20094,23 +20100,23 @@ <int value="7" label="Unknown error"/> </enum> -<enum name="InstantAppsCallSource" type="int"> +<enum name="InstantAppsCallSource"> <int value="1" label="Loading screen"/> <int value="2" label="Notification"/> </enum> -<enum name="InstantControllerEvent" type="int"> +<enum name="InstantControllerEvent"> <int value="0" label="URL_ADDED_TO_BLACKLIST"/> <int value="1" label="URL_REMOVED_FROM_BLACKLIST"/> <int value="2" label="URL_BLOCKED_BY_BLACKLIST"/> </enum> -<enum name="InstantExtended_CacheableNTPLoad" type="int"> +<enum name="InstantExtended_CacheableNTPLoad"> <int value="0" label="Failed to load"/> <int value="1" label="Loaded successfuly"/> </enum> -<enum name="InstantExtended_FallbackCause" type="int"> +<enum name="InstantExtended_FallbackCause"> <int value="0" label="Fallback did not occur"/> <int value="1" label="Page not current: unknown"/> <int value="2" label="Page not current: empty instant url"/> @@ -20120,7 +20126,7 @@ <int value="6" label="Javascript disabled"/> </enum> -<enum name="InstantExtended_InstantNavigation" type="int"> +<enum name="InstantExtended_InstantNavigation"> <obsolete> Deprecated as of 10/2013. </obsolete> @@ -20131,13 +20137,13 @@ <int value="4" label="Non-extended navigation"/> </enum> -<enum name="InstantExtended_NewOptInState" type="int"> +<enum name="InstantExtended_NewOptInState"> <int value="0" label="Default"/> <int value="1" label="Opted in"/> <int value="2" label="Opted out"/> </enum> -<enum name="InstantExtended_OptInState" type="int"> +<enum name="InstantExtended_OptInState"> <obsolete> Deprecated 2013-06. </obsolete> @@ -20149,7 +20155,7 @@ <int value="5" label="Opted out both"/> </enum> -<enum name="InstantSearchClicks_PreviewScrollState" type="int"> +<enum name="InstantSearchClicks_PreviewScrollState"> <obsolete> Deprecated as of 7/2015. </obsolete> @@ -20158,7 +20164,7 @@ <int value="2" label="Scrolled to bottom."/> </enum> -<enum name="InstantSearchClicks_ReasonForSwap" type="int"> +<enum name="InstantSearchClicks_ReasonForSwap"> <obsolete> Deprecated as of 7/2015. </obsolete> @@ -20169,12 +20175,12 @@ <int value="4" label="Swapped as original failed"/> </enum> -<enum name="InstantSessionStorageNamespace" type="int"> +<enum name="InstantSessionStorageNamespace"> <int value="0" label="different"/> <int value="1" label="identical"/> </enum> -<enum name="IntelMaxMicroArchitecture" type="int"> +<enum name="IntelMaxMicroArchitecture"> <int value="0" label="Pentium"/> <int value="1" label="SSE"/> <int value="2" label="SSE2"/> @@ -20186,7 +20192,7 @@ <int value="8" label="AVX2"/> </enum> -<enum name="InternalErrorLoadEvent" type="int"> +<enum name="InternalErrorLoadEvent"> <summary>Internal Errors in the page_load_metrics system</summary> <int value="0" label="Invalid timing IPC sent from renderer (deprecated)"/> <int value="1" @@ -20211,7 +20217,7 @@ label="Subframe navigation start before main frame navigation start"/> </enum> -<enum name="InterruptReason" type="int"> +<enum name="InterruptReason"> <int value="0" label="NONE"/> <int value="1" label="FILE_FAILED"/> <int value="2" label="FILE_ACCESS_DENIED"/> @@ -20241,37 +20247,37 @@ <int value="50" label="CRASH"/> </enum> -<enum name="InvalidationNetworkChannel" type="int"> +<enum name="InvalidationNetworkChannel"> <int value="0" label="PushClientChannel"/> <int value="1" label="GCMNetworkChannel"/> </enum> -<enum name="IOSExternalURLRequestStatus" type="int"> +<enum name="IOSExternalURLRequestStatus"> <int value="0" label="MainFrameAllowed"/> <int value="1" label="SubframeAllowed"/> <int value="2" label="SubframeBlocked"/> </enum> -<enum name="IOSShareExtensionReceivedEntrySource" type="int"> +<enum name="IOSShareExtensionReceivedEntrySource"> <int value="0" label="Unknown Application"/> <int value="1" label="Chrome share extension"/> </enum> -<enum name="IOSShareExtensionReceivedEntryType" type="int"> +<enum name="IOSShareExtensionReceivedEntryType"> <int value="0" label="Invalid item"/> <int value="1" label="Cancelled item"/> <int value="2" label="Reading list item"/> <int value="3" label="Bookmark item"/> </enum> -<enum name="IOSSpotlightAction" type="int"> +<enum name="IOSSpotlightAction"> <int value="0" label="New Tab"/> <int value="1" label="New Incognito Tab"/> <int value="2" label="Voice Search"/> <int value="3" label="QR Code Scanner"/> </enum> -<enum name="IPCAttachmentBrokerPrivilegedBrokerAttachmentError" type="int"> +<enum name="IPCAttachmentBrokerPrivilegedBrokerAttachmentError"> <int value="0" label="DESTINATION_FOUND"> The brokerable attachment had a valid destination. This is the success case. </int> @@ -20327,7 +20333,7 @@ </int> </enum> -<enum name="IPCAttachmentBrokerUnprivilegedBrokerAttachmentError" type="int"> +<enum name="IPCAttachmentBrokerUnprivilegedBrokerAttachmentError"> <int value="0" label="SUCCESS"> The brokerable attachment was successfully processed. </int> @@ -20340,7 +20346,7 @@ </int> </enum> -<enum name="IPPermissionStatus" type="int"> +<enum name="IPPermissionStatus"> <int value="0" label="Unknown"/> <int value="1" label="Not requested"/> <int value="2" label="Requested but denied"/> @@ -20349,12 +20355,12 @@ <int value="4" label="Requested and granted automatically"/> </enum> -<enum name="IPv6ConnectivityStatus" type="int"> +<enum name="IPv6ConnectivityStatus"> <int value="0" label="Incomplete IPv6 Configuration"/> <int value="1" label="Complete IPv6 Configuration"/> </enum> -<enum name="IPV6ProbeResult" type="int"> +<enum name="IPV6ProbeResult"> <int value="0" label="IPV6_CANNOT_CREATE_SOCKETS"/> <int value="1" label="IPV6_CAN_CREATE_SOCKETS"/> <int value="2" label="IPV6_GETIFADDRS_FAILED"> @@ -20365,13 +20371,13 @@ <int value="5" label="IPV6_INTERFACE_ARRAY_TOO_SHORT"/> </enum> -<enum name="IsPinnedToTaskbarResult" type="int"> +<enum name="IsPinnedToTaskbarResult"> <int value="0" label="Not pinned"/> <int value="1" label="Pinned"/> <int value="2" label="Failed to determine"/> </enum> -<enum name="JavaScriptAPIName" type="int"> +<enum name="JavaScriptAPIName"> <int value="0" label="GetUserMedia"/> <int value="1" label="PeerConnection00"/> <int value="2" label="DeprecatedPeerConnection"/> @@ -20382,7 +20388,7 @@ <int value="7" label="VideoCaptureStream"/> </enum> -<enum name="JavaScriptDialogDismissalCause" type="int"> +<enum name="JavaScriptDialogDismissalCause"> <int value="0" label="Tab closed">The tab owning the dialog was closed</int> <int value="1" label="New dialog"> A new dialog was shown, closing the existing dialog @@ -20401,7 +20407,7 @@ </int> </enum> -<enum name="JumplisticonsDeleteCategory" type="int"> +<enum name="JumplisticonsDeleteCategory"> <int value="0" label="Success"/> <int value="1" label="Fail as directory name length exceeds MAX_PATH"/> <int value="2" label="Fail as directory is read-only"/> @@ -20412,7 +20418,7 @@ <int value="7" label="Fail to remove the raw directory"/> </enum> -<enum name="JumplistIconsDetailedFolderMoveCategory" type="int"> +<enum name="JumplistIconsDetailedFolderMoveCategory"> <int value="0" label="DelTargetDir Succeed - MoveFileEx Succeed - CopyFile Succeed - SourceDirRead Succeed - DelFile Succeed - DelSourceDir Succeed"/> @@ -20607,7 +20613,7 @@ SourceDirRead Fail - DelFile Fail - DelSourceDir Fail"/> </enum> -<enum name="JumplistIconsDetailedFolderOperationCategory" type="int"> +<enum name="JumplistIconsDetailedFolderOperationCategory"> <int value="0" label="Del Dest Succeed - Mov Succeed - Del Src Succeed - Create Src Succeed"/> @@ -20647,8 +20653,7 @@ label="Del Dest Fail - Mov Fail - Del Src Fail - Create Src Fail"/> </enum> -<enum name="JumplistIconsDetailedFolderOperationDeleteUpdatedCategory" - type="int"> +<enum name="JumplistIconsDetailedFolderOperationDeleteUpdatedCategory"> <int value="0" label="Del Dest Succeed - Rename Succeed - Del Src Content Succeed - Del Src Dir Succeed - Create Src Succeed"/> @@ -20747,7 +20752,7 @@ Fail - Create Src Fail"/> </enum> -<enum name="JumplisticonsfolderCategory" type="int"> +<enum name="JumplisticonsfolderCategory"> <int value="0" label="Del Succeed - Mov Succeed - Create Succeed"/> <int value="1" label="Del Fail - Mov Succeed - Create Succeed"/> <int value="2" label="Del Succeed - Mov Fail - Create Succeed"/> @@ -20758,13 +20763,13 @@ <int value="7" label="Del Fail - Mov Fail - Create Fail"/> </enum> -<enum name="JumpListIconsFolderExistOrEmptyCategory" type="int"> +<enum name="JumpListIconsFolderExistOrEmptyCategory"> <int value="0" label="Empty"/> <int value="1" label="Non-Empty"/> <int value="2" label="Doesn't exist"/> </enum> -<enum name="JumplistIconsFolderMoveCategory" type="int"> +<enum name="JumplistIconsFolderMoveCategory"> <int value="0" label="Del Succeed - MaxPathCheck Succeed - MoveFileEx Succeed - CopyDelDir Succeed"/> @@ -20814,13 +20819,13 @@ label="Del Fail -MaxPathCheck Fail - MoveFileEx Fail - CopyDelDir Fail"/> </enum> -<enum name="KeyboardControlEvent" type="int"> +<enum name="KeyboardControlEvent"> <int value="0" label="Keyboard was shown."/> <int value="1" label="Keyboard was automatically hidden."/> <int value="2" label="Keyboard was hidden by the user."/> </enum> -<enum name="KeychainMigrationStatus" type="int"> +<enum name="KeychainMigrationStatus"> <int value="0" label="Migration hasn't started"/> <int value="1" label="Migration succeeded"/> <int value="2" label="Migation failed once"/> @@ -20830,7 +20835,7 @@ <int value="6" label="Migration stopped"/> </enum> -<enum name="KioskLaunchError" type="int"> +<enum name="KioskLaunchError"> <int value="0" label="No error"/> <int value="1" label="Has pending launch"/> <int value="2" label="Cryptohome daemon not running"/> @@ -20846,14 +20851,14 @@ <int value="12" label="Unable to launch app"/> </enum> -<enum name="KioskLaunchType" type="int"> +<enum name="KioskLaunchType"> <int value="0" label="Enterprise auto launch"/> <int value="1" label="Enterprise manual launch"/> <int value="2" label="Consumer auto launch"/> <int value="3" label="Consumer manual launch"/> </enum> -<enum name="LanguageCode" type="int"> +<enum name="LanguageCode"> <summary>ISO 639 Language Codes.</summary> <int value="24929" label="Afar"/> <int value="24930" label="Abkhazian"/> @@ -21384,7 +21389,7 @@ <int value="8026721" label="Zaza"/> </enum> -<enum name="LastSettingParsed" type="int"> +<enum name="LastSettingParsed"> <obsolete> Deprecated 2015-10-05 in Issue 433475. Histogram was used temorarily for diagnosing crash causes. @@ -21400,7 +21405,7 @@ <int value="8" label="HandleUpdateOrigins Invalid"/> </enum> -<enum name="LaunchErrorCodes" type="int"> +<enum name="LaunchErrorCodes"> <int value="0" label="SBOX_ALL_OK"/> <int value="1" label="SBOX_ERROR_GENERIC"/> <int value="2" label="SBOX_ERROR_BAD_PARAMS"/> @@ -21449,12 +21454,12 @@ <int value="1003" label="LAUNCH_RESULT_FAILURE"/> </enum> -<enum name="LaunchFromHomeScreen" type="int"> +<enum name="LaunchFromHomeScreen"> <int value="0" label="Launched as standalone web app"/> <int value="1" label="Launched as a tab"/> </enum> -<enum name="LaunchFromHomeScreenSource" type="int"> +<enum name="LaunchFromHomeScreenSource"> <int value="0" label="Unknown"/> <int value="1" label="Menu item (deprecated in M57+)"/> <int value="2" label="App banner"/> @@ -21469,14 +21474,14 @@ <int value="11" label="Unknown (WebAPK)"/> </enum> -<enum name="LaunchIntentFlags" type="int"> +<enum name="LaunchIntentFlags"> <int value="0" label="No flags"/> <int value="524288" label="NEW_DOCUMENT"/> <int value="268435456" label="NEW_TASK"/> <int value="268959744" label="NEW_TASK | NEW_DOCUMENT"/> </enum> -<enum name="LaunchMode" type="int"> +<enum name="LaunchMode"> <int value="1" label="LM_AS_WEBAPP"> Launched as an installed web application </int> @@ -21504,7 +21509,7 @@ </int> </enum> -<enum name="LazyCSSParseUsage" type="int"> +<enum name="LazyCSSParseUsage"> <int value="0" label=">= 0%"/> <int value="1" label="> 10%"/> <int value="2" label="> 25%"/> @@ -21514,13 +21519,13 @@ <int value="6" label="= 100%"/> </enum> -<enum name="LevelDBCorruptionRestoreValue" type="int"> +<enum name="LevelDBCorruptionRestoreValue"> <int value="0" label="Database Delete Success"/> <int value="1" label="Database Delete Failure"/> <int value="2" label="Database Repair Success"/> </enum> -<enum name="LevelDBCorruptionTypes" type="int"> +<enum name="LevelDBCorruptionTypes"> <int value="0" label="other"/> <int value="1" label="missing files"/> <int value="2" label="log record too small"/> @@ -21555,24 +21560,24 @@ <int value="31" label="file is too short"/> </enum> -<enum name="LevelDBDatabaseCorruptionRestoreValue" type="int"> +<enum name="LevelDBDatabaseCorruptionRestoreValue"> <int value="0" label="Delete Success"/> <int value="1" label="Delete Failure"/> <int value="2" label="Repair Success"/> </enum> -<enum name="LevelDBErrorCount" type="int"> +<enum name="LevelDBErrorCount"> <int value="1" label="Failure"/> </enum> -<enum name="LevelDBErrorTypes" type="int"> +<enum name="LevelDBErrorTypes"> <int value="0" label="NotFound"/> <int value="1" label="Corruption"/> <int value="2" label="IOError"/> <int value="3" label="Other"/> </enum> -<enum name="LevelDBIOErrorMethods" type="int"> +<enum name="LevelDBIOErrorMethods"> <int value="0" label="SequentialFileRead"/> <int value="1" label="SequentialFileSkip"/> <int value="2" label="RandomAccessFileRead"/> @@ -21597,7 +21602,7 @@ <int value="21" label="NewAppendableFile"/> </enum> -<enum name="LevelDBStatus" type="int"> +<enum name="LevelDBStatus"> <int value="0" label="OK"/> <int value="1" label="Not Found"/> <int value="2" label="Corruption"/> @@ -21606,12 +21611,12 @@ <int value="5" label="IO Error"/> </enum> -<enum name="LevelDBValueCorruptionDeleteValue" type="int"> +<enum name="LevelDBValueCorruptionDeleteValue"> <int value="0" label="Delete Success"/> <int value="1" label="Delete Failure"/> </enum> -<enum name="LibraryLoadFromApkStatus" type="int"> +<enum name="LibraryLoadFromApkStatus"> <int value="0" label="Unknown"/> <int value="1" label="Not supported">obsolete</int> <int value="2" label="Supported">obsolete</int> @@ -21620,20 +21625,20 @@ <int value="5" label="Used no map executable support fallback">obsolete</int> </enum> -<enum name="LinkMonitorFailureType" type="int"> +<enum name="LinkMonitorFailureType"> <int value="0" label="Local MAC Address Not Found"/> <int value="1" label="Client Startup Failure"/> <int value="2" label="Transmission Failure"/> <int value="3" label="Failure Threshold Reached"/> </enum> -<enum name="LinuxAudioIO" type="int"> +<enum name="LinuxAudioIO"> <int value="0" label="PulseAudio"/> <int value="1" label="ALSA"/> <int value="2" label="Cras"/> </enum> -<enum name="LinuxBackendUsage" type="int"> +<enum name="LinuxBackendUsage"> <int value="0" label="KDE_NOFLAG_PLAINTEXT"/> <int value="1" label="KDE_NOFLAG_KWALLET"/> <int value="2" label="KDE_KWALLETFLAG_PLAINTEXT"/> @@ -21657,7 +21662,7 @@ <int value="20" label="OTHER_LIBSECRET"/> </enum> -<enum name="LinuxDistro" type="int"> +<enum name="LinuxDistro"> <int value="0" label="Unknown"/> <int value="1" label="Ubuntu Other"/> <int value="2" label="Ubuntu 14.04"/> @@ -21673,7 +21678,7 @@ <int value="12" label="Fedora 25"/> </enum> -<enum name="LinuxGlibcVersion" type="int"> +<enum name="LinuxGlibcVersion"> <int value="0" label="Not Parseable"/> <int value="1" label="Unknown"/> <int value="2" label="2.11"/> @@ -21697,7 +21702,7 @@ <int value="20" label="2.29"/> </enum> -<enum name="LinuxNotificationBridgeStatusCode" type="int"> +<enum name="LinuxNotificationBridgeStatusCode"> <int value="0" label="success"/> <int value="1" label="native notifications not supported"/> <int value="2" label="missing required capabilities"/> @@ -21705,7 +21710,7 @@ <int value="4" label="(DEPRECATED) incompatible spec version"/> </enum> -<enum name="LinuxSandboxStatus" type="int"> +<enum name="LinuxSandboxStatus"> <int value="0" label="none"/> <int value="1" label="suid"/> <int value="2" label="pidns"/> @@ -21842,7 +21847,7 @@ <int value="2147483648" label="Invalid"/> </enum> -<enum name="LinuxWindowManagerName" type="int"> +<enum name="LinuxWindowManagerName"> <int value="0" label="Other"/> <int value="1" label="Blackbox"/> <int value="2" label="Chrome OS"/> @@ -21869,7 +21874,7 @@ <int value="23" label="Unnamed"/> </enum> -<enum name="LoadLibraryResultCategory" type="int"> +<enum name="LoadLibraryResultCategory"> <int value="0" label="LoadLibraryExW Succeeded"/> <int value="1" label="LoadLibraryExW Fail, LoadLibraryW Succeeded"/> <int value="2" label="LoadLibraryExW Fail, LoadLibraryW Fail"/> @@ -21877,7 +21882,7 @@ <int value="4" label="LoadLibraryExW Unavailable, LoadLibraryW Fail"/> </enum> -<enum name="LoadType" type="int"> +<enum name="LoadType"> <int value="0" label="UNDEFINED_LOAD">Not yet initialized</int> <int value="1" label="RELOAD">User pressed reload</int> <int value="2" label="HISTORY_LOAD">Back or forward</int> @@ -21894,19 +21899,19 @@ <int value="9" label="PRERENDER_LOAD">Speculative prerendering of a page</int> </enum> -<enum name="LocalRendererSinkStates" type="int"> +<enum name="LocalRendererSinkStates"> <int value="0" label="SinkStarted"/> <int value="1" label="SinkNeverStarted"/> </enum> -<enum name="LocalStorageOpenError" type="int"> +<enum name="LocalStorageOpenError"> <int value="0" label="Directory open failed"/> <int value="1" label="Database open failed"/> <int value="2" label="Invalid schema version"/> <int value="3" label="Error reading schema version"/> </enum> -<enum name="LockScreenProgress" type="int"> +<enum name="LockScreenProgress"> <int value="0" label="Start screen lock"/> <int value="1" label="Enter password correctly"/> <int value="2" label="Choose pin or password"/> @@ -21914,12 +21919,12 @@ <int value="4" label="Confirm pin"/> </enum> -<enum name="LoginConsumerWhitelist" type="int"> +<enum name="LoginConsumerWhitelist"> <int value="0" label="ANY_USER_ALLOWED">Any user can sign in</int> <int value="1" label="ONLY_WHITELISTED_ALLOWED">Whitelisted users only</int> </enum> -<enum name="LoginCustomFlags" type="int"> +<enum name="LoginCustomFlags"> <!-- Values in LoginCustomFlags are: value=(uint32_t)MD5(label). This enum is verified by AboutFlagsHistogramTest unit test. @@ -23157,7 +23162,7 @@ <int value="2141463681" label="enable-offer-upload-credit-cards"/> </enum> -<enum name="LoginDatabaseInitError" type="int"> +<enum name="LoginDatabaseInitError"> <int value="0" label="Init success"/> <int value="1" label="Can't open file"/> <int value="2" label="Start transaction error"/> @@ -23169,7 +23174,7 @@ <int value="8" label="Commit transaction error"/> </enum> -<enum name="LoginFailureReason" type="int"> +<enum name="LoginFailureReason"> <int value="0" label="None"/> <int value="1" label="Could not mount cryptohome"/> <int value="2" label="Could not mount tmpfs"/> @@ -23185,17 +23190,17 @@ <int value="12" label="Failed to get OAuth2 token"/> </enum> -<enum name="LoginIsKnownUser" type="int"> +<enum name="LoginIsKnownUser"> <int value="0" label="Unknown user"/> <int value="1" label="Known user"/> </enum> -<enum name="LoginPasswordChangeFlow" type="int"> +<enum name="LoginPasswordChangeFlow"> <int value="0" label="Password change"/> <int value="1" label="Cryptohome failure"/> </enum> -<enum name="LoginPolicyFilesState" type="int"> +<enum name="LoginPolicyFilesState"> <summary>Policy/owner key file state.</summary> <int value="0" label="HEALTHY_R11">Healthy, pre-R11</int> <int value="1" label="UNUSED">Unused</int> @@ -23251,7 +23256,7 @@ <int value="43" label="RESERVED">Reserved</int> </enum> -<enum name="LoginReauthReasons" type="int"> +<enum name="LoginReauthReasons"> <int value="0" label="None"> No reason recorded so far, nothing to report. This value should never be reported in histogram. @@ -23286,7 +23291,7 @@ </int> </enum> -<enum name="LoginStateKeyGenerationStatus" type="int"> +<enum name="LoginStateKeyGenerationStatus"> <summary>The result of a state key generation operation.</summary> <int value="0" label="GENERATION_METHOD_IDENTIFIER_HASH"> Successfully generated state keys from machine identifiers. @@ -23304,14 +23309,14 @@ <int value="5" label="HMAC_SIGN_FAILURE">HMAC computation failed.</int> </enum> -<enum name="LoginSuccessReason" type="int"> +<enum name="LoginSuccessReason"> <int value="0" label="OFFLINE_AND_ONLINE"> Login success offline and online </int> <int value="1" label="OFFLINE_ONLY">Login success offline only</int> </enum> -<enum name="LoginUserType" type="int"> +<enum name="LoginUserType"> <int value="0" label="INCOGNITO_NORMAL">Incognito Normal</int> <int value="1" label="OWNER_NORMAL">Owner Normal</int> <int value="2" label="OTHER_NORMAL">Other Normal</int> @@ -23320,7 +23325,7 @@ <int value="5" label="OTHER_DEVELOPER">Other Dev</int> </enum> -<enum name="MacBookVersions" type="int"> +<enum name="MacBookVersions"> <int value="0" label="Other"/> <int value="1" label="MacBook5,X"/> <int value="2" label="MacBook6,X"/> @@ -23346,12 +23351,12 @@ <int value="22" label="MacBookPro5,X"/> </enum> -<enum name="MainFrameStorable" type="int"> +<enum name="MainFrameStorable"> <int value="0" label="Storable"/> <int value="1" label="cache-control: no-store"/> </enum> -<enum name="MainThreadScrollingReason" type="int"> +<enum name="MainThreadScrollingReason"> <int value="0" label="Not scrolling on main"/> <int value="1" label="Background attachment fixed"/> <int value="2" label="Non layer viewport constrained"/> @@ -23378,14 +23383,14 @@ <int value="23" label="Is not stacking context"/> </enum> -<enum name="MakeChromeDefaultResult" type="int"> +<enum name="MakeChromeDefaultResult"> <int value="0" label="Chrome made default"/> <int value="1" label="Dialog closed without explicit choice"/> <int value="2" label="Other browser selected"/> <int value="3" label="Chrome made default + Relaunch in Metro (obsolete)"/> </enum> -<enum name="ManagedUserPasswordChange" type="int"> +<enum name="ManagedUserPasswordChange"> <int value="0" label="OK_MANAGER">Changed in manager session</int> <int value="1" label="OK_MANGED">Changed in supervised user session</int> <int value="2" label="FAILED_NO_MASTER_KEY">Master key not found</int> @@ -23411,13 +23416,13 @@ </int> </enum> -<enum name="ManifestFetchResultType" type="int"> +<enum name="ManifestFetchResultType"> <int value="0" label="Fetch succeeded"/> <int value="1" label="Fetch failed because of empty URL"/> <int value="2" label="Fetch failed (unspecified reason)"/> </enum> -<enum name="MappedCSSProperties" type="int"> +<enum name="MappedCSSProperties"> <!-- Generated from third_party/WebKit/Source/core/frame/UseCounter.cpp --> <int value="1" label="Total Pages Measured"/> @@ -24006,7 +24011,7 @@ <int value="584" label="scroll-snap-stop"/> </enum> -<enum name="MappedEditingCommands" type="int"> +<enum name="MappedEditingCommands"> <!-- Generated from third_party/WebKit/Source/core/editing/EditorCommand.cpp --> <int value="1" label="AlignJustified"/> @@ -24150,7 +24155,7 @@ <int value="139" label="AlignCenter"/> </enum> -<enum name="MarkHttpAsStatus" type="int"> +<enum name="MarkHttpAsStatus"> <int value="0" label="Neutral (deprecated February 2017)"/> <int value="1" label="Non-Secure"/> <int value="2" label="Neutral with a verbose warning on sensitive fields"/> @@ -24161,7 +24166,7 @@ Incognito mode"/> </enum> -<enum name="MarkNonSecureAsStatus" type="int"> +<enum name="MarkNonSecureAsStatus"> <obsolete> Deprecated 09/2016 and replaced with MarkHttpAsStatus. </obsolete> @@ -24170,20 +24175,20 @@ <int value="2" label="Non-Secure"/> </enum> -<enum name="MayLaunchUrlType" type="int"> +<enum name="MayLaunchUrlType"> <int value="0" label="No MayLaunchUrl() call."/> <int value="1" label="Low confidence."/> <int value="2" label="High confidence."/> <int value="3" label="Low and High confidence."/> </enum> -<enum name="MediaCommand" type="int"> +<enum name="MediaCommand"> <int value="0" label="Resume"/> <int value="1" label="Pause"/> <int value="2" label="Seek"/> </enum> -<enum name="MediaContainers" type="int"> +<enum name="MediaContainers"> <int value="0" label="Unknown"/> <int value="1" label="AAC (Advanced Audio Coding)"/> <int value="2" label="AC-3"/> @@ -24226,12 +24231,12 @@ <int value="39" label="SmoothStream"/> </enum> -<enum name="MediaControlsDownloadReason" type="int"> +<enum name="MediaControlsDownloadReason"> <int value="0" label="Shown"/> <int value="1" label="Clicked"/> </enum> -<enum name="MediaControlsShowReason" type="int"> +<enum name="MediaControlsShowReason"> <int value="0" label="Attribute"/> <int value="1" label="Fullscreen"/> <int value="2" label="No scripts allowed"/> @@ -24239,12 +24244,12 @@ <int value="4" label="Disabled by settings"/> </enum> -<enum name="MediaDocumentDownloadButtonType" type="int"> +<enum name="MediaDocumentDownloadButtonType"> <int value="0" label="Shown"/> <int value="1" label="Clicked"/> </enum> -<enum name="MediaElementAutoPlay" type="int"> +<enum name="MediaElementAutoPlay"> <obsolete> Deprecated 11/2016 in Issue 666370 with the deprecation of Autoplay experiment. @@ -24278,7 +24283,7 @@ <int value="21" label="Gesture requirement overridden by play method."/> </enum> -<enum name="MediaGalleriesUsageType" type="int"> +<enum name="MediaGalleriesUsageType"> <int value="0" label="Gallery added from permission dialog"/> <int value="1" label="Gallery permission added from permission dialog"/> <int value="2" label="Gallery permission removed from permission dialog"/> @@ -24312,50 +24317,50 @@ <int value="27" label="iPhoto file system used this session (obsolete)"/> </enum> -<enum name="MediaKeyError" type="int"> +<enum name="MediaKeyError"> <int value="1" label="kUnknownError"/> <int value="2" label="kClientError"/> <int value="4" label="kOutputError"/> </enum> -<enum name="MediaKeyException" type="int"> +<enum name="MediaKeyException"> <int value="0" label="kUnknownResultId"/> <int value="1" label="kSuccess"/> <int value="2" label="kKeySystemNotSupported"/> <int value="3" label="kInvalidPlayerState"/> </enum> -<enum name="MediaKeySystemSupportStatus" type="int"> +<enum name="MediaKeySystemSupportStatus"> <int value="0" label="Queried"/> <int value="1" label="Supported"/> <int value="2" label="Queried with type"/> <int value="3" label="Supported with type"/> </enum> -<enum name="MediaLoadType" type="int"> +<enum name="MediaLoadType"> <int value="0" label="URL"/> <int value="1" label="MediaSource"/> <int value="2" label="MediaStream"/> </enum> -<enum name="MediaNotificationClickSource" type="int"> +<enum name="MediaNotificationClickSource"> <int value="0" label="Media"/> <int value="1" label="Presentation"/> <int value="2" label="MediaFling"/> </enum> -<enum name="MediaOutputProtectionStatus" type="int"> +<enum name="MediaOutputProtectionStatus"> <int value="0" label="Queried"/> <int value="1" label="No external link"/> <int value="2" label="All external links protected"/> </enum> -<enum name="MediaPlayerExitStatus" type="int"> +<enum name="MediaPlayerExitStatus"> <int value="0" label="No errors"/> <int value="1" label="Has errors"/> </enum> -<enum name="MediaRouteProviderResult" type="int"> +<enum name="MediaRouteProviderResult"> <int value="0" label="UnknownError"/> <int value="1" label="Ok"/> <int value="2" label="TimedOut"/> @@ -24367,14 +24372,14 @@ <int value="8" label="Cancelled"/> </enum> -<enum name="MediaRouteProviderVersion" type="int"> +<enum name="MediaRouteProviderVersion"> <int value="0" label="Unknown"/> <int value="1" label="SameVersionAsChrome"/> <int value="2" label="OneVersionBehindChrome"/> <int value="3" label="MultipleVersionsBehindChrome"/> </enum> -<enum name="MediaRouteProviderWakeReason" type="int"> +<enum name="MediaRouteProviderWakeReason"> <int value="0" label="CreateRoute"/> <int value="1" label="JoinRoute"/> <int value="2" label="TerminateRoute"/> @@ -24397,41 +24402,41 @@ <int value="19" label="CreateMediaRouteController"/> </enum> -<enum name="MediaRouteProviderWakeup" type="int"> +<enum name="MediaRouteProviderWakeup"> <int value="0" label="Success"/> <int value="1" label="ErrorUnknown"/> <int value="2" label="ErrorTooManyRetries"/> </enum> -<enum name="MediaRouterCreateRouteOutcome" type="int"> +<enum name="MediaRouterCreateRouteOutcome"> <int value="0" label="Success"/> <int value="1" label="Failure No Route"/> <int value="2" label="Failure Invalid Sink"/> </enum> -<enum name="MediaRouterDialogOpenOrigin" type="int"> +<enum name="MediaRouterDialogOpenOrigin"> <int value="0" label="Toolbar"/> <int value="1" label="Overflow Menu"/> <int value="2" label="Contextual Menu"/> <int value="3" label="Page"/> </enum> -<enum name="MediaRouterInitialViews" type="int"> +<enum name="MediaRouterInitialViews"> <int value="0" label="Route Details"/> <int value="1" label="Sink List"/> </enum> -<enum name="MediaRouterSinkPositionLabel" type="int"> +<enum name="MediaRouterSinkPositionLabel"> <int value="100" label="100+"/> </enum> -<enum name="MediaRouterSourceTypes" type="int"> +<enum name="MediaRouterSourceTypes"> <int value="1" label="App"/> <int value="2" label="Tab"/> <int value="4" label="Desktop"/> </enum> -<enum name="MediaRouterUserAction" type="int"> +<enum name="MediaRouterUserAction"> <int value="0" label="Change Mode"/> <int value="1" label="Start Local"/> <int value="2" label="Stop Local"/> @@ -24440,18 +24445,18 @@ <int value="5" label="Replace Local Route"/> </enum> -<enum name="MediaRouteType" type="int"> +<enum name="MediaRouteType"> <int value="0" label="Local"/> <int value="1" label="Remote"/> </enum> -<enum name="MediaSessionActionSource" type="int"> +<enum name="MediaSessionActionSource"> <int value="0" label="Media Notification"/> <int value="1" label="MediaSession (Android)"/> <int value="2" label="Headset Unplugged"/> </enum> -<enum name="MediaSessionSuspendedSource" type="int"> +<enum name="MediaSessionSuspendedSource"> <int value="0" label="System Transient"/> <int value="1" label="System Permanent"/> <int value="2" label="UI"/> @@ -24459,7 +24464,7 @@ <int value="4" label="System Transient Duck"/> </enum> -<enum name="MediaSessionUserAction" type="int"> +<enum name="MediaSessionUserAction"> <int value="0" label="Play"/> <int value="1" label="Play (default handler)"/> <int value="2" label="Pause"/> @@ -24471,7 +24476,7 @@ <int value="8" label="Seek forward"/> </enum> -<enum name="MediaStreamRequestResult" type="int"> +<enum name="MediaStreamRequestResult"> <int value="0" label="Ok"/> <int value="1" label="Permission Denied"/> <int value="2" label="Permission Dismissed"/> @@ -24487,13 +24492,13 @@ <int value="12" label="Failed due to shutdown"/> </enum> -<enum name="MediaStreamRequestState" type="int"> +<enum name="MediaStreamRequestState"> <int value="0" label="Explicitly Cancelled"/> <int value="1" label="Stream Not Generated"/> <int value="2" label="Pending Media Tracks"/> </enum> -<enum name="MediaTimelineAbsTimeDelta" type="int"> +<enum name="MediaTimelineAbsTimeDelta"> <int value="0" label="[0, 1ms)"/> <int value="1" label="[1ms, 16ms)"/> <int value="2" label="[16ms, 32ms)"/> @@ -24521,7 +24526,7 @@ <int value="24" label="[16h, inf)"/> </enum> -<enum name="MediaTimelinePercent" type="int"> +<enum name="MediaTimelinePercent"> <int value="0" label="[-100.0%, -90.0%]"/> <int value="1" label="(-90.0%, -80.0%]"/> <int value="2" label="(-80.0%, -70.0%]"/> @@ -24575,7 +24580,7 @@ <int value="50" label="[90.0%, 100.0%]"/> </enum> -<enum name="MediaTimelineSeekType" type="int"> +<enum name="MediaTimelineSeekType"> <int value="0" label="Click"/> <int value="1" label="Drag from current position"/> <int value="2" label="Drag from elsewhere"/> @@ -24584,7 +24589,7 @@ <int value="5" label="Keyboard home/end key"/> </enum> -<enum name="MediaTimelineTimeDelta" type="int"> +<enum name="MediaTimelineTimeDelta"> <int value="0" label="(-inf, -16h]"/> <int value="1" label="(-16h, -8h]"/> <int value="2" label="(-8h, -4h]"/> @@ -24636,25 +24641,25 @@ <int value="48" label="[16h, inf)"/> </enum> -<enum name="MediaTypePredictionResult" type="int"> +<enum name="MediaTypePredictionResult"> <int value="0" label="All correct"/> <int value="1" label="All incorrect"/> <int value="2" label="Path-based was better"/> <int value="3" label="URL-based was better"/> </enum> -<enum name="MediaUrlType" type="int"> +<enum name="MediaUrlType"> <int value="0" label="Non Http Live Stream Type"/> <int value="1" label="Http Live Stream Type"/> </enum> -<enum name="MemoryPressureLevel" type="int"> +<enum name="MemoryPressureLevel"> <int value="0" label="No memory pressure"/> <int value="1" label="Moderate memory pressure"/> <int value="2" label="Critical memory pressure"/> </enum> -<enum name="MemoryPressureLevelChanges" type="int"> +<enum name="MemoryPressureLevelChanges"> <int value="0" label="No pressure to moderate pressure"/> <int value="1" label="No pressure to critical pressure"/> <int value="2" label="Moderate pressure to critical pressure"/> @@ -24663,20 +24668,20 @@ <int value="5" label="Moderate pressure to no pressure"/> </enum> -<enum name="MemoryState" type="int"> +<enum name="MemoryState"> <int value="0" label="Normal"/> <int value="1" label="Throttled"/> <int value="2" label="Suspended"/> </enum> -<enum name="MessageLoopProblems" type="int"> +<enum name="MessageLoopProblems"> <int value="0" label="Message Post"/> <int value="1" label="Completion Post"/> <int value="2" label="Set Timer"/> <int value="3" label="Received WM_QUIT"/> </enum> -<enum name="MetadataReadResult" type="int"> +<enum name="MetadataReadResult"> <int value="0" label="Success"/> <int value="1" label="Open failure"/> <int value="2" label="Not found"/> @@ -24687,13 +24692,13 @@ <int value="7" label="Malformed data"/> </enum> -<enum name="MetadataWriteResult" type="int"> +<enum name="MetadataWriteResult"> <int value="0" label="Success"/> <int value="1" label="Serialization failure"/> <int value="2" label="Write failure"/> </enum> -<enum name="MetaTagTypeEnum" type="int"> +<enum name="MetaTagTypeEnum"> <int value="0" label="No viewport tag"/> <int value="1" label="Viewport meta with device width"/> <int value="2" label="Viewport meta with constant width"/> @@ -24703,7 +24708,7 @@ <int value="6" label="XHTML-MP document type"/> </enum> -<enum name="MetricsReportingChange" type="int"> +<enum name="MetricsReportingChange"> <int value="0" label="Error"> Error occurred while updating MetricsReporting </int> @@ -24711,7 +24716,7 @@ <int value="2" label="Enabled successfully"/> </enum> -<enum name="MhtmlGenerationFinalSaveStatus" type="int"> +<enum name="MhtmlGenerationFinalSaveStatus"> <int value="0" label="Success"/> <int value="1" label="File closing error"/> <int value="2" label="File creation error"/> @@ -24721,19 +24726,19 @@ <int value="6" label="Render process no longer exists"/> </enum> -<enum name="MicrophoneMuteResult" type="int"> +<enum name="MicrophoneMuteResult"> <int value="0" label="Muted"/> <int value="1" label="Not muted"/> </enum> -<enum name="MidiResult" type="int"> +<enum name="MidiResult"> <int value="0" label="Not initialized"/> <int value="1" label="Successfully initialized"/> <int value="2" label="Not supported"/> <int value="3" label="Generic initialization error"/> </enum> -<enum name="MidiUsage" type="int"> +<enum name="MidiUsage"> <int value="0" label="Instantiated"/> <int value="1" label="Instantiated on unsupported platforms"/> <int value="2" label="Session is started"/> @@ -24743,19 +24748,19 @@ <int value="6" label="Output port is added"/> </enum> -<enum name="MigrationNssToPemNetworkTypes" type="int"> +<enum name="MigrationNssToPemNetworkTypes"> <int value="0" label="EAP"/> <int value="1" label="OpenVPN"/> <int value="2" label="IPsec"/> </enum> -<enum name="MigrationUIFirstScreen" type="int"> +<enum name="MigrationUIFirstScreen"> <int value="0" label="Ready"/> <int value="1" label="Resume"/> <int value="2" label="LowStorage"/> </enum> -<enum name="MigrationUIMigrationResult" type="int"> +<enum name="MigrationUIMigrationResult"> <int value="0" label="Success in new migration"/> <int value="1" label="Success in resumed migration"/> <int value="2" label="General failure in new migration"/> @@ -24766,14 +24771,14 @@ <int value="7" label="Mount failure in resumed migration"/> </enum> -<enum name="MigrationUIRemoveCryptohomeResult" type="int"> +<enum name="MigrationUIRemoveCryptohomeResult"> <int value="0" label="Success in new migration"/> <int value="1" label="Success in resumed migration"/> <int value="2" label="Failure in new migration"/> <int value="3" label="Failure in resumed migration"/> </enum> -<enum name="MigrationUIScreen" type="int"> +<enum name="MigrationUIScreen"> <int value="0" label="Initial"/> <int value="1" label="Ready"/> <int value="2" label="Migrating"/> @@ -24781,7 +24786,7 @@ <int value="4" label="Not enough storage"/> </enum> -<enum name="MigrationUIUserChoice" type="int"> +<enum name="MigrationUIUserChoice"> <int value="0" label="Update"/> <int value="1" label="Skip"/> <int value="2" label="Restart on migration failure"/> @@ -24789,7 +24794,7 @@ <int value="4" label="Report an issue"/> </enum> -<enum name="MissingStartType" type="int"> +<enum name="MissingStartType"> <int value="0" label="Nothing missing"/> <int value="1" label="Start missing"/> <int value="2" label="Commit missing"/> @@ -24800,12 +24805,12 @@ <int value="7" label="NavStart+Start+Commit missing"/> </enum> -<enum name="MistSwitchResult" type="int"> +<enum name="MistSwitchResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> </enum> -<enum name="MobileDefaultBrowserState" type="int"> +<enum name="MobileDefaultBrowserState"> <int value="0" label="No default"/> <int value="1" label="Chrome: System default"/> <int value="2" label="Chrome: Installed default"/> @@ -24813,7 +24818,7 @@ <int value="4" label="Other: Installed default"/> </enum> -<enum name="MobileDownloadCancelReason" type="int"> +<enum name="MobileDownloadCancelReason"> <int value="0" label="Not canceled"/> <int value="1" label="Click on the cancel button"/> <int value="2" label="Notification dismissed"/> @@ -24825,7 +24830,7 @@ <int value="8" label="Cancelled by native for other reasons"/> </enum> -<enum name="MobileDownloadInterceptFailureReason" type="int"> +<enum name="MobileDownloadInterceptFailureReason"> <int value="0" label="No failure"/> <int value="1" label="Empty url"/> <int value="2" label="Non http or https"/> @@ -24835,7 +24840,7 @@ <int value="6" label="Use channel bound cookies"/> </enum> -<enum name="MobileDownloadResumption" type="int"> +<enum name="MobileDownloadResumption"> <int value="0" label="Resumption button shown after manual pause"/> <int value="1" label="Resumption button shown after browser is killed"/> <int value="2" label="Resumption button clicked"/> @@ -24843,7 +24848,7 @@ <int value="4" label="Resumption auto started"/> </enum> -<enum name="MobileFreProgress" type="int"> +<enum name="MobileFreProgress"> <int value="0" label="FRE started"/> <int value="1" label="Welcome shown"/> <int value="2" label="Data saver shown"/> @@ -24853,7 +24858,7 @@ <int value="6" label="Search engine choice dialog shown"/> </enum> -<enum name="MobileFreSignInChoice" type="int"> +<enum name="MobileFreSignInChoice"> <summary> These values are defined inside the MobileFreSignInChoice enum chrome/browser/android/metrics/uma_bridge.cc and reference possible ways of @@ -24866,7 +24871,7 @@ <int value="4" label="No thanks"/> </enum> -<enum name="MobileHungRendererInfoBarEvent" type="int"> +<enum name="MobileHungRendererInfoBarEvent"> <int value="0" label="Clicked the 'Wait' button"/> <int value="1" label="Clicked the 'Kill' button"/> <int value="2" label="Clicked the 'X' (close) button)"/> @@ -24874,7 +24879,7 @@ <int value="4" label="Infobar dismissed after tab closed"/> </enum> -<enum name="MobileSessionShutdownType" type="int"> +<enum name="MobileSessionShutdownType"> <int value="0" label="Shutdown in background"/> <int value="1" label="Shutdown in foreground; no log; no memory warning"/> <int value="2" label="Shutdown in foreground; with log; no memory warning"/> @@ -24883,7 +24888,7 @@ <int value="5" label="First launch after upgrade"/> </enum> -<enum name="MobileStartingAction" type="int"> +<enum name="MobileStartingAction"> <int value="0" label="No activity"/> <int value="1" label="Open new tab"/> <int value="2" label="Focus omnibox"/> @@ -24893,13 +24898,13 @@ <int value="6" label="Open tab switcher"/> </enum> -<enum name="ModuleIndex" type="int"> +<enum name="ModuleIndex"> <int value="0" label="chrome.dll"/> <int value="1" label="chrome_elf.dll"/> <int value="2" label="ntdll.dll"/> </enum> -<enum name="MojoMachPortRelayBrokerError" type="int"> +<enum name="MojoMachPortRelayBrokerError"> <int value="0" label="SUCCESS"> The Mach port was successfully sent or received. </int> @@ -24923,14 +24928,14 @@ </int> </enum> -<enum name="MojoMachPortRelayChildError" type="int"> +<enum name="MojoMachPortRelayChildError"> <int value="0" label="SUCCESS">The Mach port was successfully received.</int> <int value="1" label="ERROR_RECEIVE_MACH_MESSAGE"> An error occurred while trying to receive a Mach port with mach_msg(). </int> </enum> -<enum name="MostVisitedTileIndex" type="int"> +<enum name="MostVisitedTileIndex"> <summary> Index of a tile on the new tab page. This is only an enum so that the dashboard won't produce misleading statistics like averages. @@ -24949,7 +24954,7 @@ <int value="11" label="11"/> </enum> -<enum name="MotionEventToolType" type="int"> +<enum name="MotionEventToolType"> <summary>The type of tool that triggers a pointer-type MotionEvent.</summary> <int value="0" label="Unknown">Unknown tool type.</int> <int value="1" label="Finger">The tool is a finger (touch).</int> @@ -24960,12 +24965,12 @@ </int> </enum> -<enum name="MouseEventFollowedByClick" type="int"> +<enum name="MouseEventFollowedByClick"> <int value="0" label="Missed event before click"/> <int value="1" label="Caught event before click"/> </enum> -<enum name="MSECodec" type="int"> +<enum name="MSECodec"> <int value="0" label="(Unknown)"/> <int value="1" label="VP8"/> <int value="2" label="VP9"/> @@ -24981,7 +24986,7 @@ <int value="12" label="DOLBYVISION"/> </enum> -<enum name="MultiAccountUpdateBubbleUserAction" type="int"> +<enum name="MultiAccountUpdateBubbleUserAction"> <int value="0" label="DEFAULT_ACCOUNT_MATCHED_BY_PASSWORD_USER_CHANGED"/> <int value="1" label="DEFAULT_ACCOUNT_MATCHED_BY_PASSWORD_USER_NOT_CHANGED"/> <int value="2" @@ -24994,7 +24999,7 @@ <int value="8" label="DEFAULT_ACCOUNT_FIRST_USER_REJECTED_UPDATE"/> </enum> -<enum name="MultiChromeFrameRemovalResult" type="int"> +<enum name="MultiChromeFrameRemovalResult"> <int value="0" label="ALL_FAILED">All removal operations failed.</int> <int value="1" label="PARTIAL_SUCCESS"> Some, but not all, operations succeeded. @@ -25002,30 +25007,30 @@ <int value="2" label="SUCCESS">All operations succeeded.</int> </enum> -<enum name="MultiProfileSessionMode" type="int"> +<enum name="MultiProfileSessionMode"> <int value="0" label="Single user mode"/> <int value="1" label="Side by side mode"/> <int value="2" label="Separate desktop mode"/> </enum> -<enum name="MultiProfileSigninUserAction" type="int"> +<enum name="MultiProfileSigninUserAction"> <int value="0" label="System tray"/> <int value="1" label="Browser frame"/> </enum> -<enum name="MultiProfileSwitchActiveUserAction" type="int"> +<enum name="MultiProfileSwitchActiveUserAction"> <int value="0" label="System tray"/> <int value="1" label="Keyboard accelerator"/> </enum> -<enum name="MultiProfileTeleportWindowAction" type="int"> +<enum name="MultiProfileTeleportWindowAction"> <int value="0" label="Drag and drop"/> <int value="1" label="Caption context menu"/> <int value="2" label="Return by minimize"/> <int value="3" label="Return by launcher"/> </enum> -<enum name="MultiProfileTeleportWindowType" type="int"> +<enum name="MultiProfileTeleportWindowType"> <int value="0" label="Tabbed browser"/> <int value="1" label="Tabbed incognito browser"/> <int value="2" label="V1 app"/> @@ -25035,7 +25040,7 @@ <int value="6" label="Unknown"/> </enum> -<enum name="NaClHelperStatus" type="int"> +<enum name="NaClHelperStatus"> <int value="0" label="Helper not initialized"/> <int value="1" label="Helper executable missing"/> <int value="2" label="Helper bootstrap executable missing"/> @@ -25045,7 +25050,7 @@ <int value="6" label="Helper started correctly"/> </enum> -<enum name="NaClHttpStatusCodeClass" type="int"> +<enum name="NaClHttpStatusCodeClass"> <int value="0" label="0XX"/> <int value="1" label="1XX"/> <int value="2" label="2XX"/> @@ -25055,12 +25060,12 @@ <int value="6" label="No status"/> </enum> -<enum name="NaClManifestType" type="int"> +<enum name="NaClManifestType"> <int value="0" label="File"/> <int value="1" label="DataURI"/> </enum> -<enum name="NaClOSArchEnum" type="int"> +<enum name="NaClOSArchEnum"> <int value="0" label="Linux x86-32"/> <int value="1" label="Linux x86-64"/> <int value="2" label="Linux ARM"/> @@ -25073,7 +25078,7 @@ <int value="9" label="Linux Mips32"/> </enum> -<enum name="NaClPluginErrorCode" type="int"> +<enum name="NaClPluginErrorCode"> <int value="0" label="ERROR_LOAD_SUCCESS"/> <int value="1" label="ERROR_LOAD_ABORTED"/> <int value="2" label="ERROR_UNKNOWN"/> @@ -25147,7 +25152,7 @@ <int value="70" label="ERROR_NEXE_NOACCESS_URL"/> </enum> -<enum name="NaClSelLdrErrorCode" type="int"> +<enum name="NaClSelLdrErrorCode"> <int value="0" label="LOAD_OK"/> <int value="1" label="LOAD_STATUS_UNKNOWN"/> <int value="2" label="LOAD_UNSUPPORTED_OS_PLATFORM"/> @@ -25216,18 +25221,18 @@ <int value="65" label="LOAD_NO_MEMORY_FOR_ADDRESS_SPACE"/> </enum> -<enum name="NaClStartupEnum" type="int"> +<enum name="NaClStartupEnum"> <int value="0" label="Default tab opened"/> <int value="1" label="New tab opened"/> <int value="2" label="NaCl sel_ldr started"/> </enum> -<enum name="NaClValidationCacheEnum" type="int"> +<enum name="NaClValidationCacheEnum"> <int value="0" label="Miss"/> <int value="1" label="Hit"/> </enum> -<enum name="NativeLibraryPreloaderResult" type="int"> +<enum name="NativeLibraryPreloaderResult"> <int value="0" label="SUCCESS"/> <int value="1" label="WRONG_PACKAGE_NAME"/> <int value="2" label="ADDRESS_SPACE_NOT_RESERVED"/> @@ -25240,14 +25245,14 @@ <int value="10" label="FAILED_TO_FIND_NAMESPACE"/> </enum> -<enum name="NatTypeCounters" type="int"> +<enum name="NatTypeCounters"> <int value="0" label="Not behind a NAT."/> <int value="1" label="Behind a NAT of unknown type."/> <int value="2" label="Behind a Symmetric NAT."/> <int value="3" label="Behind a Non-Symmetric NAT."/> </enum> -<enum name="NavigationCacheEnum" type="int"> +<enum name="NavigationCacheEnum"> <int value="0" label="Validate cache"/> <int value="1" label="Bypass cache"/> <int value="2" label="Skip cache validation"/> @@ -25255,7 +25260,7 @@ <int value="4" label="Disable cache"/> </enum> -<enum name="NavigationDirection" type="int"> +<enum name="NavigationDirection"> <obsolete> Deprecated as of Chrome 59 in favour of OverscrollNavigationType. </obsolete> @@ -25265,19 +25270,19 @@ <int value="2" label="Back">Scrolled back</int> </enum> -<enum name="NavigationInterceptResult" type="int"> +<enum name="NavigationInterceptResult"> <int value="0" label="Created external intent"/> <int value="1" label="Created external intent with tab clobbering"/> <int value="2" label="Created async dialog for confirming external intent"/> <int value="3" label="Navigation not intercepted"/> </enum> -<enum name="NavigationIsSameProcess" type="int"> +<enum name="NavigationIsSameProcess"> <int value="0" label="Cross process navigation"/> <int value="1" label="Same process navigation"/> </enum> -<enum name="NavigationScheme" type="int"> +<enum name="NavigationScheme"> <int value="0" label="(Unknown)"/> <int value="1" label="http"/> <int value="2" label="https"/> @@ -25291,12 +25296,12 @@ <int value="10" label="filesystem"/> </enum> -<enum name="NavigationWasServedFromCache" type="int"> +<enum name="NavigationWasServedFromCache"> <int value="0" label="Navigation wasn't served from cache"/> <int value="1" label="Navigation was served from cache"/> </enum> -<enum name="NavigatorVibrationType" type="int"> +<enum name="NavigatorVibrationType"> <int value="0" label="Main frame vibrate, no user gesture"/> <int value="1" label="Main frame vibrate, with user gesture"/> <int value="2" label="Same-origin subframe vibrate, no user gesture"/> @@ -25305,7 +25310,7 @@ <int value="5" label="Cross-origin subframe vibrate, with user gesture"/> </enum> -<enum name="NCNGetActiveNetworkInfoResult" type="int"> +<enum name="NCNGetActiveNetworkInfoResult"> <int value="0" label="Active network was disconnected"/> <int value="1" label="Active network was already connected"/> <int value="2" label="Android API level was too old for unblocking"/> @@ -25314,7 +25319,7 @@ <int value="5" label="Active network was unblocked"/> </enum> -<enum name="NegativeSampleReason" type="int"> +<enum name="NegativeSampleReason"> <int value="0" label="Persistent sparse histogram had logged value but no active sample."/> @@ -25340,14 +25345,14 @@ accumulation and became negative."/> </enum> -<enum name="NetCacheState" type="int"> +<enum name="NetCacheState"> <int value="0" label="FROM_CACHE"/> <int value="1" label="STILL_VALID"/> <int value="2" label="NO_LONGER_VALID"/> <int value="3" label="NO_ENTRY"/> </enum> -<enum name="NetConnectivityProtocolStatus" type="int"> +<enum name="NetConnectivityProtocolStatus"> <int value="0" label="SUCCESS"/> <int value="1" label="IP_STRING_PARSE_FAILED"/> <int value="2" label="SOCKET_CREATE_FAILED"/> @@ -25371,7 +25376,7 @@ <int value="20" label="STATUS_MAX"/> </enum> -<enum name="NetConnectivityStatus" type="int"> +<enum name="NetConnectivityStatus"> <int value="0" label="SUCCESS"/> <int value="1" label="IP_STRING_PARSE_FAILED"/> <int value="2" label="SOCKET_CREATE_FAILED"/> @@ -25384,7 +25389,7 @@ <int value="9" label="STATUS_MAX"/> </enum> -<enum name="NetErrorCodes" type="int"> +<enum name="NetErrorCodes"> <!-- Generated from net/base/net_error_list.h --> <int value="0" label="OK"/> @@ -25614,7 +25619,7 @@ <int value="806" label="DNS_SORT_ERROR"/> </enum> -<enum name="NetErrorNavigationCorrectionTypes" type="int"> +<enum name="NetErrorNavigationCorrectionTypes"> <int value="0" label="Google cached page"/> <int value="1" label="URL correction"/> <int value="2" label="Alt URL - domain"/> @@ -25626,7 +25631,7 @@ <int value="100" label="Web search query"/> </enum> -<enum name="NetErrorPageEvents" type="int"> +<enum name="NetErrorPageEvents"> <int value="0" label="Error Page Shown"/> <int value="1" label="Reload Button Shown"/> <int value="2" label="Reload Button Clicked"/> @@ -25653,7 +25658,7 @@ <int value="23" label="Download Button Clicked"/> </enum> -<enum name="NetFilterType" type="int"> +<enum name="NetFilterType"> <summary> Specific content decoding filter. See net::Filter::FilterType for more details @@ -25667,7 +25672,7 @@ <int value="6" label="Unsupported"/> </enum> -<enum name="NetFilterType2" type="int"> +<enum name="NetFilterType2"> <summary> Specific content decoding filter. See net::SourceStream::SourceType for more details @@ -25693,12 +25698,12 @@ </int> </enum> -<enum name="NetInternalsUiFeature" type="int"> +<enum name="NetInternalsUiFeature"> <int value="0" label="NetInternals"/> <int value="1" label="Connection tester"/> </enum> -<enum name="NetPreconnectUtilization" type="int"> +<enum name="NetPreconnectUtilization"> <int value="0" label="non-speculative, never connected"/> <int value="1" label="non-speculative, never used"/> <int value="2" label="non-speculative and used"/> @@ -25710,7 +25715,7 @@ <int value="8" label="subresource and used"/> </enum> -<enum name="Network3GGobiError" type="int"> +<enum name="Network3GGobiError"> <summary> These error indexes are produced by QCErrorToMetricIndex() in gobi-cromo-plugin. @@ -25719,7 +25724,7 @@ <int value="1" label="QMI_HARDWARE_RESTRICTED"/> </enum> -<enum name="NetworkAuthModeType" type="int"> +<enum name="NetworkAuthModeType"> <int value="0" label="UNKNOWN"/> <int value="1" label="EAP-AKA"/> <int value="2" label="EAP-FAST"/> @@ -25740,7 +25745,7 @@ <int value="17" label="EAP-TTLS"/> </enum> -<enum name="NetworkCellular3GPPRegistrationDelayedDrop" type="int"> +<enum name="NetworkCellular3GPPRegistrationDelayedDrop"> <int value="0" label="Delayed drop posted"> A signal loss in the cellular service was detected and a delayed connection drop request was posted. This request causes the cellular connection to be @@ -25752,13 +25757,13 @@ </int> </enum> -<enum name="NetworkCellularOutOfCreditsReason" type="int"> +<enum name="NetworkCellularOutOfCreditsReason"> <int value="0" label="Connect-Disconnect Loop"/> <int value="1" label="TX-Queue Congestion"/> <int value="2" label="Elongated Time Wait"/> </enum> -<enum name="NetworkCellularTechnology" type="int"> +<enum name="NetworkCellularTechnology"> <int value="0" label="1XRTT"/> <int value="1" label="EDGE"/> <int value="2" label="EVDO"/> @@ -25771,7 +25776,7 @@ <int value="9" label="Unknown"/> </enum> -<enum name="NetworkCellularUsageRequestStatus" type="int"> +<enum name="NetworkCellularUsageRequestStatus"> <summary> Status code that we received in response to a cellular usage API request. </summary> @@ -25789,7 +25794,7 @@ <int value="7" label="Unknown Device"/> </enum> -<enum name="NetworkChannelType" type="int"> +<enum name="NetworkChannelType"> <int value="0" label="UNDEF"/> <int value="1" label="2412"/> <int value="2" label="2417"/> @@ -25835,7 +25840,7 @@ <int value="42" label="5230"/> </enum> -<enum name="NetworkClockStates" type="int"> +<enum name="NetworkClockStates"> <int value="0" label="NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC: accuracy of system clock is unknown because there is no information available from the @@ -25872,12 +25877,12 @@ pending"/> </enum> -<enum name="NetworkConnectionIPType" type="int"> +<enum name="NetworkConnectionIPType"> <int value="0" label="IPv4"/> <int value="1" label="IPv6"/> </enum> -<enum name="NetworkConnectionType" type="int"> +<enum name="NetworkConnectionType"> <int value="0" label="Unknown"/> <int value="1" label="Ethernet"/> <int value="2" label="WiFi"/> @@ -25888,11 +25893,11 @@ <int value="7" label="Bluetooth"/> </enum> -<enum name="NetworkCorruptedProfile" type="int"> +<enum name="NetworkCorruptedProfile"> <int value="0" label="Corrupted Profile"/> </enum> -<enum name="NetworkDhcpClientStatus" type="int"> +<enum name="NetworkDhcpClientStatus"> <int value="0" label="Arp Gateway"> The DHCP client will attempt to identify the default gateway using a unicast ARP to the gateway's MAC address. This may help speed up the re-connection @@ -25959,16 +25964,16 @@ </int> </enum> -<enum name="NetworkDHCPOptionFailure" type="int"> +<enum name="NetworkDHCPOptionFailure"> <int value="0" label="DHCP Option Failure"/> </enum> -<enum name="NetworkDisconnectType" type="int"> +<enum name="NetworkDisconnectType"> <int value="0" label="System Disconnect"/> <int value="1" label="User Disconnect"/> </enum> -<enum name="NetworkErrorType" type="int"> +<enum name="NetworkErrorType"> <int value="0" label="Unknown"/> <int value="1" label="Portal"/> <int value="2" label="Offline"/> @@ -25977,7 +25982,7 @@ <int value="5" label="None"/> </enum> -<enum name="NetworkLocationRequestEvent" type="int"> +<enum name="NetworkLocationRequestEvent"> <int value="0" label="REQUEST_START"/> <int value="1" label="REQUEST_CANCEL"/> <int value="2" label="RESPONSE_SUCCESS"/> @@ -25987,7 +25992,7 @@ <int value="6" label="RESPONSE_INVALID_FIX"/> </enum> -<enum name="NetworkPhyModeType" type="int"> +<enum name="NetworkPhyModeType"> <int value="0" label="UNDEF"/> <int value="1" label="802.11a"/> <int value="2" label="802.11b"/> @@ -25998,7 +26003,7 @@ <int value="7" label="802.11ac"/> </enum> -<enum name="NetworkPortalResult" type="int"> +<enum name="NetworkPortalResult"> <summary> The portal result types come from PortalResult in shill/metrics.h </summary> @@ -26014,12 +26019,12 @@ <int value="9" label="Unknown"/> </enum> -<enum name="NetworkProblemType" type="int"> +<enum name="NetworkProblemType"> <int value="0" label="Congested TCP Queue"/> <int value="1" label="DNS Failure"/> </enum> -<enum name="NetworkQueueStopReason" type="int"> +<enum name="NetworkQueueStopReason"> <summary>The stop reasons come from shill/mac80211_monitor.h.</summary> <int value="0" label="Device Driver"/> <int value="1" label="Power Save"/> @@ -26030,12 +26035,12 @@ <int value="6" label="Channel Type Change"/> </enum> -<enum name="NetworkQuietStatus" type="int"> +<enum name="NetworkQuietStatus"> <int value="0" label="Had network 0-quiet for 0.5 seconds"/> <int value="1" label="Had network 2-quiet for 2 seconds"/> </enum> -<enum name="NetworkSecurityType" type="int"> +<enum name="NetworkSecurityType"> <summary> The security types come from the connman_service_security enum in flimflam/include/service.h @@ -26049,7 +26054,7 @@ <int value="6" label="PSK"/> </enum> -<enum name="NetworkServiceError" type="int"> +<enum name="NetworkServiceError"> <int value="0" label="UNKNOWN"/> <int value="1" label="AAA_FAILED"/> <int value="2" label="ACTIVATION_FAILED"/> @@ -26073,7 +26078,7 @@ <int value="20" label="PIN_MISSING"/> </enum> -<enum name="NetworkTechnology" type="int"> +<enum name="NetworkTechnology"> <int value="0" label="Cellular"/> <int value="1" label="Ethernet"/> <int value="2" label="Ethernet EAP"/> @@ -26083,7 +26088,7 @@ <int value="6" label="Unknown"/> </enum> -<enum name="NewTabPageActionAndroid" type="int"> +<enum name="NewTabPageActionAndroid"> <obsolete> Deprecated as of 01/2017. Replaced by NewTabPageActionAndroid2. </obsolete> @@ -26101,7 +26106,7 @@ label="Clicked on the Refresh button in the all dismissed state"/> </enum> -<enum name="NewTabPageActionAndroid2" type="int"> +<enum name="NewTabPageActionAndroid2"> <int value="0" label="Searched using the omnibox"/> <int value="1" label="Navigated to Google search homepage using the omnibox"/> <int value="2" label="Navigated to any other page using the omnibox"/> @@ -26116,7 +26121,7 @@ label="Clicked on the Refresh button in the all dismissed state"/> </enum> -<enum name="NewTabPageBookmarkActionAndroid" type="int"> +<enum name="NewTabPageBookmarkActionAndroid"> <summary> These values are defined in PartnerBookmarkAction enum in chrome/browser/ui/webui/ntp/android/bookmarks_handler.cc. @@ -26127,13 +26132,13 @@ <int value="3" label="Renamed root partner folder"/> </enum> -<enum name="NewTabPageLogoClick" type="int"> +<enum name="NewTabPageLogoClick"> <int value="0" label="Static logo clicked"/> <int value="1" label="CTA image clicked"/> <int value="2" label="Animated logo clicked"/> </enum> -<enum name="NewTabPageLogoDownloadOutcome" type="int"> +<enum name="NewTabPageLogoDownloadOutcome"> <summary> These values are defined in LogoDownloadOutcome enum in components/search_provider_logos/logo_tracker.h. @@ -26146,12 +26151,12 @@ <int value="5" label="Logo revalidated"/> </enum> -<enum name="NewTabPageLogoShown" type="int"> +<enum name="NewTabPageLogoShown"> <int value="0" label="Static logo shown"/> <int value="1" label="CTA image shown"/> </enum> -<enum name="NewTabPageMobilePromo" type="int"> +<enum name="NewTabPageMobilePromo"> <summary> These values are defined inside the PromoImpressionBuckets enum in chrome/browser/ui/webui/ntp/android/promo_handler.cc @@ -26163,13 +26168,13 @@ <int value="4" label="User dismissed the promo"/> </enum> -<enum name="NewTabType" type="int"> +<enum name="NewTabType"> <int value="0" label="New tab button"/> <int value="1" label="Regular menu option"/> <int value="2" label="Tab strip menu option"/> </enum> -<enum name="NewTabURLState" type="int"> +<enum name="NewTabURLState"> <int value="0" label="Valid URL was used"/> <int value="1" label="Corrupt state"/> <int value="2" label="Incognito window"/> @@ -26179,12 +26184,12 @@ <int value="6" label="URL blocked for supervised user"/> </enum> -<enum name="NewUserPriorityPrefsSyncResult" type="int"> +<enum name="NewUserPriorityPrefsSyncResult"> <int value="0" label="Succeeded"/> <int value="1" label="Timed out"/> </enum> -<enum name="NormalizedScore" type="int"> +<enum name="NormalizedScore"> <int value="0" label="Underflow bucket"/> <int value="1" label="Score in (0, 0.1]"/> <int value="2" label="Score in (0.1, 0.2]"/> @@ -26199,7 +26204,7 @@ <int value="11" label="Overflow bucket"/> </enum> -<enum name="NoStatePrefetchResponseType" type="int"> +<enum name="NoStatePrefetchResponseType"> <int value="0" label="Sub-resource, cacheable"/> <int value="1" label="Sub-resource, no-store"/> <int value="2" label="Sub-resource redirect, cacheable"/> @@ -26210,7 +26215,7 @@ <int value="7" label="Main resource redirect, no-store"/> </enum> -<enum name="NoteTakingAppLaunchResult" type="int"> +<enum name="NoteTakingAppLaunchResult"> <int value="0" label="Chrome app launched successfully"/> <int value="1" label="Chrome app missing"/> <int value="2" label="Android app launched successfully"/> @@ -26221,7 +26226,7 @@ <int value="7" label="No apps available"/> </enum> -<enum name="NotificationActionType" type="int"> +<enum name="NotificationActionType"> <int value="0" label="Unknown"/> <int value="1" label="Notification added"/> <int value="2" label="Notification updated"/> @@ -26232,14 +26237,14 @@ <int value="7" label="Notification closed by system"/> </enum> -<enum name="NotificationAppStatus" type="int"> +<enum name="NotificationAppStatus"> <int value="0" label="Undeterminable (old Android version)"/> <int value="1" label="Undeterminable (exception thrown)"/> <int value="2" label="Enabled"/> <int value="3" label="Disabled"/> </enum> -<enum name="NotificationDatabaseStatus" type="int"> +<enum name="NotificationDatabaseStatus"> <int value="0" label="OK"/> <int value="1" label="Not found error"/> <int value="2" label="Corruption error"/> @@ -26249,21 +26254,21 @@ <int value="6" label="Invalid Argument error"/> </enum> -<enum name="NotifierType" type="int"> +<enum name="NotifierType"> <int value="0" label="Application"/> <int value="1" label="Arc++"/> <int value="2" label="Web Page"/> <int value="3" label="System Component"/> </enum> -<enum name="NotifyResult" type="int"> +<enum name="NotifyResult"> <int value="0" label="PROCESS_NONE"/> <int value="1" label="PROCESS_NOTIFIED"/> <int value="2" label="PROFILE_IN_USE"/> <int value="3" label="LOCK_ERROR"/> </enum> -<enum name="NotStreamingReason" type="int"> +<enum name="NotStreamingReason"> <int value="0" label="Already loaded"/> <int value="1" label="Not HTTP"/> <int value="2" label="Reload"/> @@ -26274,7 +26279,7 @@ <int value="7" label="Script too small"/> </enum> -<enum name="NPAPIPluginStatus" type="int"> +<enum name="NPAPIPluginStatus"> <int value="0" label="Unsupported"> NPAPI is not supported on this platform </int> @@ -26282,7 +26287,7 @@ <int value="2" label="Enabled">NPAPI is enabled</int> </enum> -<enum name="NQEEffectiveConnectionType" type="int"> +<enum name="NQEEffectiveConnectionType"> <int value="0" label="Unknown"/> <int value="1" label="Offline"/> <int value="2" label="Slow 2G"/> @@ -26296,7 +26301,7 @@ </int> </enum> -<enum name="NQEExternalEstimateProviderStatus" type="int"> +<enum name="NQEExternalEstimateProviderStatus"> <int value="0" label="External estimate provider was not available"/> <int value="1" label="External estimate provider was available"/> <int value="2" label="External estimate provider was queried"/> @@ -26308,7 +26313,7 @@ provider"/> </enum> -<enum name="NQEObservationSource" type="int"> +<enum name="NQEObservationSource"> <int value="0" label="HTTP"/> <int value="1" label="TCP"/> <int value="2" label="QUIC"/> @@ -26319,7 +26324,7 @@ <int value="7" label="Transport-layer default"/> </enum> -<enum name="NtpFollowAction" type="int"> +<enum name="NtpFollowAction"> <int value="0" label="PAGE_TRANSITION_LINK"/> <int value="1" label="PAGE_TRANSITION_TYPED"/> <int value="2" label="PAGE_TRANSITION_AUTO_BOOKMARK"/> @@ -26336,12 +26341,12 @@ <int value="13" label="Other action"/> </enum> -<enum name="NTPImpressionType" type="int"> +<enum name="NTPImpressionType"> <int value="0" label="regular NTP impression"/> <int value="1" label="potential NTP impression - no open tab"/> </enum> -<enum name="NTPLayout" type="int"> +<enum name="NTPLayout"> <int value="0" label="Doesn't fit, not expanding to cut off most likely"/> <int value="1" label="Doesn't fit, expanding to cut off most likely"/> <int value="2" label="Fits, field trial is not enabled"/> @@ -26350,13 +26355,13 @@ <int value="5" label="Layout is condensed"/> </enum> -<enum name="NTPLoadType" type="int"> +<enum name="NTPLoadType"> <int value="0" label="Cold startup"/> <int value="1" label="Warm startup"/> <int value="2" label="Other, not at startup"/> </enum> -<enum name="NtpMostVisitedScheme" type="int"> +<enum name="NtpMostVisitedScheme"> <obsolete> Deprecated 2016-05. </obsolete> @@ -26371,27 +26376,27 @@ <int value="8" label="javascript://"/> </enum> -<enum name="NtpPaneType" type="int"> +<enum name="NtpPaneType"> <int value="1" label="MostVisited"/> <int value="2" label="Apps"/> <int value="3" label="Bookmarks"/> <int value="4" label="Suggestions"/> </enum> -<enum name="NtpPromoAction" type="int"> +<enum name="NtpPromoAction"> <int value="0" label="NTP Promo viewed"/> <int value="1" label="NTP Promo closed"/> <int value="2" label="NTP Promo link clicked"/> </enum> -<enum name="NtpRequestThrottlerStatus" type="int"> +<enum name="NtpRequestThrottlerStatus"> <int value="0" label="Interactive request - quota granted"/> <int value="1" label="Background request - quota granted"/> <int value="2" label="Background request - quota exceeded"/> <int value="3" label="Interactive request - quota exceeded"/> </enum> -<enum name="NtpSnippetsFetchResult" type="int"> +<enum name="NtpSnippetsFetchResult"> <int value="0" label="Success"/> <int value="1" label="Empty hosts - deprecated"/> <int value="2" label="URLRequestStatus error"/> @@ -26404,7 +26409,7 @@ <int value="9" label="No API key available"/> </enum> -<enum name="NTPSnippetsState" type="int"> +<enum name="NTPSnippetsState"> <summary> The state of the RemoteSuggestionsProvider (formerly known as NTPSnippetsService). @@ -26416,12 +26421,12 @@ <int value="3" label="Error"/> </enum> -<enum name="NtpSuggestionsType" type="int"> +<enum name="NtpSuggestionsType"> <int value="0" label="Client suggestion"/> <int value="1" label="Server suggestion"/> </enum> -<enum name="NtpTileExperimentActions" type="int"> +<enum name="NtpTileExperimentActions"> <summary> The types of actions performed by the Most Visited Tile Placement experiment, used to identify the cases where the experiment could not @@ -26433,7 +26438,7 @@ <int value="3" label="Too few URLs, didn't flip tiles 1 and 4"/> </enum> -<enum name="NTPTileVisualType" type="int"> +<enum name="NTPTileVisualType"> <summary>The visual type of a most visited tile on the new tab page.</summary> <int value="0" label="None">The icon or thumbnail hasn't loaded yet.</int> <int value="1" label="IconReal"> @@ -26464,7 +26469,7 @@ </int> </enum> -<enum name="NTSTATUS" type="int"> +<enum name="NTSTATUS"> <int value="-1073741818" label="0xC0000006 - STATUS_IN_PAGE_ERROR"/> <int value="-1073741808" label="0xC0000010 - STATUS_INVALID_DEVICE_REQUEST"/> <int value="-1073741803" label="0xC0000015 - STATUS_NONEXISTENT_SECTOR"/> @@ -26481,7 +26486,7 @@ <int value="0" label="0x00000000 - STATUS_SUCCESS"/> </enum> -<enum name="NullableBoolean" type="int"> +<enum name="NullableBoolean"> <summary> A Nullable Boolean can True, False or Null (ie: unset or absent). </summary> @@ -26490,13 +26495,13 @@ <int value="2" label="Null"/> </enum> -<enum name="OAuth2LoginAccountRevokedMigrationState" type="int"> +<enum name="OAuth2LoginAccountRevokedMigrationState"> <int value="0" label="Account ID migration not started"/> <int value="1" label="Account ID migration in progress"/> <int value="2" label="Account ID migration done"/> </enum> -<enum name="OAuth2LoginSeedState" type="int"> +<enum name="OAuth2LoginSeedState"> <int value="0" label="Account was seeded before FireRefreshTokenRevoked"/> <int value="1" label="Account was seeded before FireRefreshTokenAvailable"/> <int value="2" label="Account was not seeded before FireRefreshTokenRevoked"/> @@ -26504,7 +26509,7 @@ label="Account was not seeded before FireRefreshTokenAvailable"/> </enum> -<enum name="OfflinePagesAggregatedRequestResult" type="int"> +<enum name="OfflinePagesAggregatedRequestResult"> <int value="0" label="Show offline page on disconnected network"/> <int value="1" label="Page not found on disconnected network"/> <int value="2" label="Show offline page on flaky network"/> @@ -26523,7 +26528,7 @@ <int value="15" label="Redirected on connected network"/> </enum> -<enum name="OfflinePagesBackgroundImmediateStartStatus" type="int"> +<enum name="OfflinePagesBackgroundImmediateStartStatus"> <int value="0" label="Started"/> <int value="1" label="Busy"/> <int value="2" label="Not accepted by loader"/> @@ -26533,7 +26538,7 @@ <int value="5" label="Not started on svelte device"/> </enum> -<enum name="OfflinePagesBackgroundOfflinerRequestStatus" type="int"> +<enum name="OfflinePagesBackgroundOfflinerRequestStatus"> <!-- Generated from components/offline_pages/background/offliner.h --> <int value="0" label="Unknown (not expected to be recorded)"/> @@ -26596,7 +26601,7 @@ </int> </enum> -<enum name="OfflinePagesBackgroundSavePageResult" type="int"> +<enum name="OfflinePagesBackgroundSavePageResult"> <!-- Generated from components/offline_pages/core/background/request_notifier.h --> <int value="0" label="Success">Request was completed successfully.</int> @@ -26630,19 +26635,19 @@ </int> </enum> -<enum name="OfflinePagesCctApiPrerenderAllowedStatus" type="int"> +<enum name="OfflinePagesCctApiPrerenderAllowedStatus"> <int value="0" label="PrerenderAllowed"/> <int value="1" label="ThirdPartyCookiesDisabled"/> <int value="2" label="NetworkPredictionDisabled"/> </enum> -<enum name="OfflinePagesClearAllStatus" type="int"> +<enum name="OfflinePagesClearAllStatus"> <int value="0" label="Success"/> <int value="1" label="Store reset failed"/> <int value="2" label="Store reload failed"/> </enum> -<enum name="OfflinePagesClearStorageResult" type="int"> +<enum name="OfflinePagesClearStorageResult"> <int value="0" label="Success"/> <int value="1" label="Unnecessary to clean"/> <int value="2" label="Page expiration failed (deprecated 11/2016)"/> @@ -26651,7 +26656,7 @@ label="Both expiration and deletion failed (deprecated 11/2016)"/> </enum> -<enum name="OfflinePagesDeletePageResult" type="int"> +<enum name="OfflinePagesDeletePageResult"> <int value="0" label="Success"/> <int value="1" label="Cancelled"/> <int value="2" label="Store failure"/> @@ -26659,14 +26664,14 @@ <int value="4" label="Not found"/> </enum> -<enum name="OfflinePagesLoadStatus" type="int"> +<enum name="OfflinePagesLoadStatus"> <int value="0" label="Success"/> <int value="1" label="Store init failed"/> <int value="2" label="Store load failed"/> <int value="3" label="Data parsing failed"/> </enum> -<enum name="OfflinePagesRedirectResult" type="int"> +<enum name="OfflinePagesRedirectResult"> <obsolete> Deprecated 2016-08. </obsolete> @@ -26682,7 +26687,7 @@ <int value="9" label="Redirect loop online"/> </enum> -<enum name="OfflinePagesSavePageResult" type="int"> +<enum name="OfflinePagesSavePageResult"> <int value="0" label="Success">Page was saved successfully.</int> <int value="1" label="Cancelled">Page save was cancelled in the interim.</int> <int value="2" label="Device full"> @@ -26719,12 +26724,12 @@ </int> </enum> -<enum name="OfflinePagesSharedPageWasOffline" type="int"> +<enum name="OfflinePagesSharedPageWasOffline"> <int value="0" label="Online"/> <int value="1" label="Offline"/> </enum> -<enum name="OfflinePagesTabRestoreType" type="int"> +<enum name="OfflinePagesTabRestoreType"> <int value="0" label="While online"> Tab was successfully restored while the device was online. Can help assess the potential benefit of allowing loading from offline pages even when the @@ -26773,7 +26778,7 @@ </int> </enum> -<enum name="OfflineStatus" type="int"> +<enum name="OfflineStatus"> <obsolete> Deprecated 4/2015. </obsolete> @@ -26784,14 +26789,14 @@ <int value="4" label="Server offline and stale data not available."/> </enum> -<enum name="OffscreenCanvasCommitType" type="int"> +<enum name="OffscreenCanvasCommitType"> <int value="0" label="GPUCanvasGPUCompositing"/> <int value="1" label="GPUCanvasSoftwareCompositing"/> <int value="2" label="SoftwareCanvasGPUCompositing"/> <int value="3" label="SoftwareCanvasSoftwareCompositing"/> </enum> -<enum name="OmniboxAggressiveHistoryURLProviderFieldTrialBeacon" type="int"> +<enum name="OmniboxAggressiveHistoryURLProviderFieldTrialBeacon"> <int value="0" label="disabled by flags"/> <int value="1" label="enabled by flags"/> <int value="2" label="auto, not in trial"/> @@ -26799,7 +26804,7 @@ <int value="4" label="auto, enabled in trial"/> </enum> -<enum name="OmniboxEnteredKeywordMode" type="int"> +<enum name="OmniboxEnteredKeywordMode"> <int value="0" label="via tab"/> <int value="1" label="via space at end"/> <int value="2" label="via space in middle"/> @@ -26809,7 +26814,7 @@ <int value="6" label="tap gesture on hint view"/> </enum> -<enum name="OmniboxInputType" type="int"> +<enum name="OmniboxInputType"> <int value="0" label="invalid"/> <int value="1" label="unknown"/> <int value="2" label="deprecated: requested url"/> @@ -26818,7 +26823,7 @@ <int value="5" label="forced query"/> </enum> -<enum name="OmniboxPageContext" type="int"> +<enum name="OmniboxPageContext"> <int value="0" label="invalid spec; shouldn't happen"/> <int value="1" label="extension-replaced new tab page OR obsolete new tab page"/> @@ -26836,7 +26841,7 @@ <int value="12" label="maps app"/> </enum> -<enum name="OmniboxProviderAndResultType" type="int"> +<enum name="OmniboxProviderAndResultType"> <int value="101" label="URL_WHAT_YOU_TYPED via HistoryURL provider"/> <int value="102" label="HISTORY_URL via HistoryURL provider"/> <int value="302" label="HISTORY_URL via HistoryQuick provider"/> @@ -26876,7 +26881,7 @@ <int value="1424" label="CLIPBOARD from Clipboard provider"/> </enum> -<enum name="OmniboxProviderType" type="int"> +<enum name="OmniboxProviderType"> <int value="1" label="HistoryURL"/> <int value="2" label="deprecated: HistoryContents"/> <int value="3" label="HistoryQuick"/> @@ -26893,7 +26898,7 @@ <int value="14" label="clipboard provider"/> </enum> -<enum name="OmniboxSearchEngine" type="int"> +<enum name="OmniboxSearchEngine"> <int value="0" label="Unknown"/> <int value="1" label="Google"/> <int value="2" label="Yahoo!"/> @@ -26974,7 +26979,7 @@ <int value="114" label="imesh.net"/> </enum> -<enum name="OmniboxSearchEngineType" type="int"> +<enum name="OmniboxSearchEngineType"> <int value="0" label="Unknown"/> <int value="1" label="AOL"/> <int value="2" label="Ask"/> @@ -27026,13 +27031,13 @@ <int value="48" label="360"/> </enum> -<enum name="OmniboxSuggestRequests" type="int"> +<enum name="OmniboxSuggestRequests"> <int value="1" label="requests sent"/> <int value="2" label="requests invalidated"/> <int value="3" label="(non-invalidated) replies received"/> </enum> -<enum name="OmniboxSummarizedResultType" type="int"> +<enum name="OmniboxSummarizedResultType"> <int value="0" label="URL"/> <int value="1" label="search"/> <int value="2" label="app/extension"/> @@ -27041,36 +27046,36 @@ <int value="5" label="unknown"/> </enum> -<enum name="OmniboxUserTextCleared" type="int"> +<enum name="OmniboxUserTextCleared"> <int value="0" label="cleared by editing"/> <int value="1" label="cleared with escape"/> </enum> -<enum name="OmniboxZeroSuggestRequests" type="int"> +<enum name="OmniboxZeroSuggestRequests"> <int value="1" label="requests sent"/> <int value="2" label="requests invalidated"/> <int value="3" label="(non-invalidated) replies received"/> </enum> -<enum name="OpenFileSystemResult" type="int"> +<enum name="OpenFileSystemResult"> <int value="0" label="OK."/> <int value="1" label="In incognito mode."/> <int value="2" label="Invalid scheme."/> <int value="3" label="Failed to create directory."/> </enum> -<enum name="OpenLinkAsUser" type="int"> +<enum name="OpenLinkAsUser"> <int value="0" label="Active profile."/> <int value="1" label="Inactive, multi-profile."/> <int value="2" label="Inactive, single-profile."/> </enum> -<enum name="OpenLinkAsUserProfilesState" type="int"> +<enum name="OpenLinkAsUserProfilesState"> <int value="0" label="No other active profiles."/> <int value="1" label="Active other profiles."/> </enum> -<enum name="OriginTrialEnableResult" type="int"> +<enum name="OriginTrialEnableResult"> <obsolete> Obsolete as of M54 and replaced by OriginTrialTokenStatus. </obsolete> @@ -27087,7 +27092,7 @@ <int value="10" label="FeatureDisabled"/> </enum> -<enum name="OriginTrialMessageGeneratedResult" type="int"> +<enum name="OriginTrialMessageGeneratedResult"> <obsolete> Obsolete as of Chrome 54. </obsolete> @@ -27096,7 +27101,7 @@ <int value="2" label="No"/> </enum> -<enum name="OriginTrialTokenStatus" type="int"> +<enum name="OriginTrialTokenStatus"> <int value="0" label="Success"/> <int value="1" label="NotSupported"/> <int value="2" label="Insecure"/> @@ -27109,7 +27114,7 @@ <int value="9" label="TokenDisabled"/> </enum> -<enum name="OSAgnosticErrno" type="int"> +<enum name="OSAgnosticErrno"> <summary>Errno values with the same meanings on Mac/Win/Linux.</summary> <int value="0" label="0">No error</int> <int value="1" label="EPERM">Operation not permitted</int> @@ -27148,13 +27153,13 @@ <int value="34" label="ERANGE">Numerical result out of range</int> </enum> -<enum name="OsSuite" type="int"> +<enum name="OsSuite"> <int value="0" label="Windows Home Edition"/> <int value="1" label="Windows Professional Edition (or better)"/> <int value="2" label="Windows Server Edition"/> </enum> -<enum name="OSXExceptionHandlerEvents" type="int"> +<enum name="OSXExceptionHandlerEvents"> <int value="0" label="EXCEPTION_ACCESSIBILITY"> Object does not support accessibility attributes </int> @@ -27178,7 +27183,7 @@ </int> </enum> -<enum name="OSXFullscreenParameters" type="int"> +<enum name="OSXFullscreenParameters"> <int value="0" label="IMMERSIVE_SECONDARY_SHARED_SINGLE">INVALID</int> <int value="1" label="APPKIT_SECONDARY_SHARED_SINGLE">INVALID</int> <int value="2" label="IMMERSIVE_PRIMARY_SHARED_SINGLE"> @@ -27221,7 +27226,7 @@ </int> </enum> -<enum name="OSXFullscreenStyle" type="int"> +<enum name="OSXFullscreenStyle"> <int value="0" label="IMMERSIVE"> The window was fullscreened using the immersive mechanism. </int> @@ -27235,7 +27240,7 @@ </int> </enum> -<enum name="OSXFullscreenWindowLocation" type="int"> +<enum name="OSXFullscreenWindowLocation"> <int value="0" label="PRIMARY_SINGLE_SCREEN"> The window was located on the primary screen, and there is only a single screen available. @@ -27250,13 +27255,13 @@ </int> </enum> -<enum name="OSXHandoffOrigin" type="int"> +<enum name="OSXHandoffOrigin"> <int value="0" label="Unknown Origin"/> <int value="1" label="Chrome on iOS"/> <int value="2" label="Chrome on Mac"/> </enum> -<enum name="OSXScreensHaveSeparateSpaces" type="int"> +<enum name="OSXScreensHaveSeparateSpaces"> <int value="0" label="CANNOT_HAVE_SEPARATE_SPACES"> The "Screens Have Separate Spaces" option is unavailable. </int> @@ -27268,7 +27273,7 @@ </int> </enum> -<enum name="OSXSharedMemoryMechanism" type="int"> +<enum name="OSXSharedMemoryMechanism"> <int value="0" label="POSIX"> The shared memory region is backed by a POSIX fd. </int> @@ -27277,7 +27282,7 @@ </int> </enum> -<enum name="OtherPossibleUsernamesUsage" type="int"> +<enum name="OtherPossibleUsernamesUsage"> <int value="0" label="Nothing to Autofill"/> <int value="1" label="No other possible usernames"/> <int value="2" label="Other possible usernames present, but none were shown"/> @@ -27285,7 +27290,7 @@ <int value="4" label="Other possible username was selected"/> </enum> -<enum name="OtherSessionsActions" type="int"> +<enum name="OtherSessionsActions"> <int value="0" label="Menu initialized"/> <int value="1" label="Menu shown"/> <int value="2" label="Link clicked"/> @@ -27299,7 +27304,7 @@ <int value="10" label="Hide for now"/> </enum> -<enum name="OutputDeviceStatus" type="int"> +<enum name="OutputDeviceStatus"> <int value="0" label="Ok"/> <int value="1" label="Not found"/> <int value="2" label="Not authorized"/> @@ -27307,14 +27312,14 @@ <int value="4" label="Internal error"/> </enum> -<enum name="OverlaySupportFlag" type="int"> +<enum name="OverlaySupportFlag"> <int value="0" label="None"/> <int value="1" label="Direct overlay support"/> <int value="2" label="Scaling overlay support"/> <int value="3" label="Direct and scaling overlay support"/> </enum> -<enum name="OverscrollMode" type="int"> +<enum name="OverscrollMode"> <summary>Direction of the overscroll gesture.</summary> <int value="1" label="North">Scrolled from bottom towards top</int> <int value="2" label="South">Scrolled from top towards the bottom</int> @@ -27322,7 +27327,7 @@ <int value="4" label="East">Scrolled from left towards right</int> </enum> -<enum name="OverscrollNavigationType" type="int"> +<enum name="OverscrollNavigationType"> <summary> Type of the overscroll gesture based on direction and source (i.e. touchpad vs. touch screen). @@ -27338,7 +27343,7 @@ </int> </enum> -<enum name="P2PLookupResult" type="int"> +<enum name="P2PLookupResult"> <int value="0" label="Found"/> <int value="1" label="Not Found"/> <int value="2" label="Vanished"/> @@ -27346,7 +27351,7 @@ <int value="4" label="Filtered"/> </enum> -<enum name="P2PServerResult" type="int"> +<enum name="P2PServerResult"> <int value="0" label="Response Sent"/> <int value="1" label="Response Interrupted"/> <int value="2" label="Malformed"/> @@ -27354,7 +27359,7 @@ <int value="4" label="Index"/> </enum> -<enum name="PacResultForStrippedUrl" type="int"> +<enum name="PacResultForStrippedUrl"> <obsolete> Deprecated 4/27/2016. No longer tracked. </obsolete> @@ -27372,7 +27377,7 @@ <int value="7" label="FAIL_DIFFERENT_PROXY_LIST"/> </enum> -<enum name="PageLoadEvent" type="int"> +<enum name="PageLoadEvent"> <obsolete> Deprecated in favor of {Committed|Provisional|InternalError}LoadEvent </obsolete> @@ -27384,14 +27389,14 @@ <int value="5" label="Successful first layout (backgrounded)"/> </enum> -<enum name="PageLoadMetricsAMPViewType" type="int"> +<enum name="PageLoadMetricsAMPViewType"> <int value="0" label="None"/> <int value="1" label="AMP Cache"/> <int value="2" label="Google Search AMP Viewer"/> <int value="3" label="Google News AMP Viewer"/> </enum> -<enum name="PageLoadTimingStatus" type="int"> +<enum name="PageLoadTimingStatus"> <summary>Status of PageLoadTimings received from the render process</summary> <int value="0" label="Valid"/> <int value="1" label="Empty timing"/> @@ -27415,7 +27420,7 @@ <int value="16" label="Invalid order - first paint / first meaningful paint"/> </enum> -<enum name="PageScaleFactorRange" type="int"> +<enum name="PageScaleFactorRange"> <int value="0" label="<25%"/> <int value="1" label="25-49%"/> <int value="2" label="50-74%"/> @@ -27439,7 +27444,7 @@ <int value="20" label=">=500%"/> </enum> -<enum name="PagespeedHeaderServerType" type="int"> +<enum name="PagespeedHeaderServerType"> <int value="0" label="Total responses"/> <int value="1" label="mod_pagespeed server"/> <int value="2" label="ngx_pagespeed server"/> @@ -27447,7 +27452,7 @@ <int value="4" label="Unknown server type"/> </enum> -<enum name="PagespeedVersion" type="int"> +<enum name="PagespeedVersion"> <summary> The version of PageSpeed. Values up to 1.6.29.x are in use as of 2013-10-01 while later values may adjust 'a' and/or 'b' arbitrarily. @@ -27553,12 +27558,12 @@ <int value="99" label="a.b.58.x"/> </enum> -<enum name="PageUsed" type="int"> +<enum name="PageUsed"> <int value="0" label="Discarded"/> <int value="1" label="Used"/> </enum> -<enum name="PageVisitTransitionType" type="int"> +<enum name="PageVisitTransitionType"> <int value="0" label="Page"/> <int value="1" label="Omnibox URL"/> <int value="2" label="Omnibox default search"/> @@ -27570,14 +27575,14 @@ <int value="8" label="Unknown"/> </enum> -<enum name="PaletteModeCancelType" type="int"> +<enum name="PaletteModeCancelType"> <int value="0" label="Palette laser pointer mode is cancelled."/> <int value="1" label="Palette laser pointer mode is switched out of"/> <int value="2" label="Palette magnify mode is cancelled."/> <int value="3" label="Palette magnify mode is switched out of."/> </enum> -<enum name="PaletteTrayOptions" type="int"> +<enum name="PaletteTrayOptions"> <int value="0" label="Palette being closed or dismissed with no action"/> <int value="1" label="Click on the settings button"/> <int value="2" label="Click on the help button"/> @@ -27588,12 +27593,12 @@ <int value="7" label="Laser pointer mode"/> </enum> -<enum name="PanningModelType" type="int"> +<enum name="PanningModelType"> <int value="0" label="equalpower"/> <int value="1" label="HRTF"/> </enum> -<enum name="ParallelDownloadCreationEvent" type="int"> +<enum name="ParallelDownloadCreationEvent"> <int value="0" label="Parallel download started"/> <int value="1" label="Fall back to normal download"/> <int value="2" label="No strong validators response headers"/> @@ -27607,12 +27612,12 @@ label="HTTP method or url scheme does not meet the requirement."/> </enum> -<enum name="ParentFrameKnown" type="int"> +<enum name="ParentFrameKnown"> <int value="0" label="Parent Frame Not Known"/> <int value="1" label="Parent Frame Known"/> </enum> -<enum name="ParsedCookieStatus" type="int"> +<enum name="ParsedCookieStatus"> <obsolete> Deprecated as of 9/2013. Experiment to measure control characters in cookies is finished. @@ -27623,12 +27628,12 @@ <int value="3" label="Cookie contains both control chars and is invalid"/> </enum> -<enum name="PassiveForcedListenerResultType" type="int"> +<enum name="PassiveForcedListenerResultType"> <int value="0" label="PreventDefaultNotCalled"/> <int value="1" label="DocumentLevelTouchPreventDefaultCalled"/> </enum> -<enum name="PasswordBubbleDisplayDisposition" type="int"> +<enum name="PasswordBubbleDisplayDisposition"> <int value="0" label="Opened automatically / Offering a password to save"/> <int value="1" label="Opened manually / Offering a password to save"/> <int value="2" label="Opened manually / Managing saved passwords"/> @@ -27643,18 +27648,18 @@ <int value="8" label="Opened automatically / Offering a password to update"/> </enum> -<enum name="PasswordBubbleSignInPromoDismissalReason" type="int"> +<enum name="PasswordBubbleSignInPromoDismissalReason"> <int value="0" label="Dismissed"/> <int value="1" label="Sign in"/> <int value="2" label="No thanks"/> </enum> -<enum name="PasswordFormQueryVolume" type="int"> +<enum name="PasswordFormQueryVolume"> <int value="0" label="New password query"/> <int value="1" label="Current query"/> </enum> -<enum name="PasswordFormType" type="int"> +<enum name="PasswordFormType"> <int value="0" label="Login form"/> <int value="1" label="Login form without username"/> <int value="2" @@ -27667,7 +27672,7 @@ <int value="7" label="Combined login and signup form"/> </enum> -<enum name="PasswordGenerationEvent" type="int"> +<enum name="PasswordGenerationEvent"> <int value="0" label="No sign up form"/> <int value="1" label="Local heuristics found sign up form"/> <int value="2" label="DEPRECATED: Icon shown"/> @@ -27683,7 +27688,7 @@ <int value="12" label="Generation triggered by autocomplete attributes"/> </enum> -<enum name="PasswordImportFromCSVResult" type="int"> +<enum name="PasswordImportFromCSVResult"> <int value="0" label="Password import succeeded"/> <int value="1" label="Password import failed due to IO error"/> <int value="2" label="Password import failed due to malformed CSV"/> @@ -27691,7 +27696,7 @@ <int value="4" label="Boundary value"/> </enum> -<enum name="PasswordManagerActionsTaken" type="int"> +<enum name="PasswordManagerActionsTaken"> <obsolete> Deprecated as of Chrome 32. See PasswordManagerActionsTakenWithPsl </obsolete> @@ -27805,7 +27810,7 @@ / form submit succeeded"/> </enum> -<enum name="PasswordManagerActionsTakenV3" type="int"> +<enum name="PasswordManagerActionsTakenV3"> <summary> The value is a combination of three different options - what did the password manager do, what did the user do, and was the form submitted (and @@ -27944,7 +27949,7 @@ username and password / form submit succeeded"/> </enum> -<enum name="PasswordManagerActionsTakenWithPsl" type="int"> +<enum name="PasswordManagerActionsTakenWithPsl"> <obsolete> Deprecated as of 3/18/2014. See PasswordManagerActionsTakenV3. </obsolete> @@ -28095,8 +28100,7 @@ / form submit succeeded"/> </enum> -<enum name="PasswordManagerAllowToCollectURLBubble.UIDismissalReason" - type="int"> +<enum name="PasswordManagerAllowToCollectURLBubble.UIDismissalReason"> <obsolete> The bubble isn't shown anymore. Become obsolete in Feb. 2015. </obsolete> @@ -28105,27 +28109,27 @@ <int value="2" label="Clicked do not collect URL"/> </enum> -<enum name="PasswordManagerEmptyUsernameField" type="int"> +<enum name="PasswordManagerEmptyUsernameField"> <int value="0" label="Has username field"/> <int value="1" label="No username field"/> </enum> -<enum name="PasswordManagerEmptyUsernamePasswordChangeForm" type="int"> +<enum name="PasswordManagerEmptyUsernamePasswordChangeForm"> <int value="0" label="Not a password change form"/> <int value="1" label="A password change form"/> </enum> -<enum name="PasswordManagerFilledAndroidCredentials" type="int"> +<enum name="PasswordManagerFilledAndroidCredentials"> <int value="0" label="NOT from Android"/> <int value="1" label="From Android"/> </enum> -<enum name="PasswordManagerOfferedAndroidCredentials" type="int"> +<enum name="PasswordManagerOfferedAndroidCredentials"> <int value="0" label="None from Android"/> <int value="1" label="1+ from Android"/> </enum> -<enum name="PasswordManagerOsPasswordStatus" type="int"> +<enum name="PasswordManagerOsPasswordStatus"> <int value="0" label="Unknown"/> <int value="1" label="Unsupported platform"/> <int value="2" label="Password is blank"/> @@ -28134,7 +28138,7 @@ label="Password status not checked as user is on a Windows Domain"/> </enum> -<enum name="PasswordManagerPreferencesInitialAndFinalValues" type="int"> +<enum name="PasswordManagerPreferencesInitialAndFinalValues"> <summary> The pair of initial values and the pair of final values for the legacy preference for controlling the Chrome Password Manager and new preference @@ -28175,7 +28179,7 @@ label="Initial state: N='on', L='on' Final state: N='on', L='on'"/> </enum> -<enum name="PasswordManagerPreferencesInitialValues" type="int"> +<enum name="PasswordManagerPreferencesInitialValues"> <summary> The pair of initial values for the legacy preference for controlling the Chrome Password Manager and new preference for controlling Smart Lock on @@ -28187,7 +28191,7 @@ <int value="3" label="New pref is 'on', legacy pref is 'on'"/> </enum> -<enum name="PasswordManagerPslDomainMatchTriggering" type="int"> +<enum name="PasswordManagerPslDomainMatchTriggering"> <summary> The value indicates whether an entry returned by password autofill contains a value that was found by matching against the public suffix list. @@ -28198,12 +28202,12 @@ <int value="3" label="Federated match"/> </enum> -<enum name="PasswordManagerShowEmptyUsername" type="int"> +<enum name="PasswordManagerShowEmptyUsername"> <int value="0" label="Non-empty username"/> <int value="1" label="Empty username"/> </enum> -<enum name="PasswordManagerSuppressedAccountCrossActionsTaken" type="int"> +<enum name="PasswordManagerSuppressedAccountCrossActionsTaken"> <summary> The value is a mixed-base encoding of the combination of four attributes: whether there were suppressed stored credentials (and the kind if there @@ -28456,7 +28460,7 @@ OverrideUsernameAndPassword)"/> </enum> -<enum name="PasswordManagerSyncingAccountState" type="int"> +<enum name="PasswordManagerSyncingAccountState"> <summary> The value is a combination of the current sync state and if the user has their sync password saved. @@ -28468,7 +28472,7 @@ label="Not Syncing/Sync pasword saved. This value should not happen."/> </enum> -<enum name="PasswordManagerUIDismissalReason" type="int"> +<enum name="PasswordManagerUIDismissalReason"> <int value="0" label="Bubble lost focus / No infobar interaction"/> <int value="1" label="Clicked 'Save'"/> <int value="2" label="Clicked 'Nope'"/> @@ -28484,7 +28488,7 @@ <int value="12" label="Clicked the link passwords.google.com"/> </enum> -<enum name="PasswordProtectionRequestOutcome" type="int"> +<enum name="PasswordProtectionRequestOutcome"> <int value="0" label="Unknown"/> <int value="1" label="Succeeded"/> <int value="2" label="Canceled"/> @@ -28502,19 +28506,19 @@ <int value="14" label="URL not valid for reputation computing"/> </enum> -<enum name="PasswordProtectionVerdict" type="int"> +<enum name="PasswordProtectionVerdict"> <int value="0" label="Verdict not specified"/> <int value="1" label="Safe"/> <int value="2" label="Low reputation"/> <int value="3" label="Phishing"/> </enum> -<enum name="PasswordReusePasswordFieldDetected" type="int"> +<enum name="PasswordReusePasswordFieldDetected"> <int value="0" label="No password field"/> <int value="1" label="Has password field"/> </enum> -<enum name="PasswordSubmissionEvent" type="int"> +<enum name="PasswordSubmissionEvent"> <int value="0" label="Password submission succeeded"/> <int value="1" label="Password submission failed"/> <int value="2" label="Password not submitted"/> @@ -28523,14 +28527,14 @@ <int value="5" label="Generated password submission would have failed"/> </enum> -<enum name="PasswordSyncState" type="int"> +<enum name="PasswordSyncState"> <int value="0" label="Syncing OK"/> <int value="1" label="Read failed"/> <int value="2" label="Duplcate tags"/> <int value="3" label="Server failed"/> </enum> -<enum name="PaymentRequestAbortReason" type="int"> +<enum name="PaymentRequestAbortReason"> <int value="0" label="DismissedByUser"/> <int value="1" label="AbortedByMerchant"/> <int value="2" label="InvalidDataFromRenderer"/> @@ -28544,7 +28548,7 @@ <int value="10" label="Merchant Navigation"/> </enum> -<enum name="PaymentRequestCanMakePaymentEffectOnShow" type="int"> +<enum name="PaymentRequestCanMakePaymentEffectOnShow"> <int value="0" label="CanMakePayment() returned false and show() was not called"/> <int value="1" label="CanMakePayment() returned false and show() was called"/> @@ -28553,26 +28557,26 @@ <int value="3" label="CanMakePayment() returned true and show() was called"/> </enum> -<enum name="PaymentRequestFlowCompletionStatus" type="int"> +<enum name="PaymentRequestFlowCompletionStatus"> <int value="0" label="Completed"/> <int value="1" label="User Aborted"/> <int value="2" label="Other Aborted"/> </enum> -<enum name="PaymentRequestNoShowReason" type="int"> +<enum name="PaymentRequestNoShowReason"> <int value="0" label="NoMatchingPaymentMethod"/> <int value="1" label="NoSupportedPaymentMethod"/> <int value="2" label="ConcurrentRequests"/> <int value="3" label="ReasonOther"/> </enum> -<enum name="PaymentRequestPaymentMethods" type="int"> +<enum name="PaymentRequestPaymentMethods"> <int value="0" label="Autofill credit cards"/> <int value="1" label="Android Pay"/> <int value="2" label="Other Payment App"/> </enum> -<enum name="PaymentRequestRequestedInformation" type="int"> +<enum name="PaymentRequestRequestedInformation"> <int value="0" label="None"/> <int value="1" label="Email"/> <int value="2" label="Phone"/> @@ -28591,39 +28595,39 @@ <int value="15" label="Email, Phone, Shipping Address and Name"/> </enum> -<enum name="PDFFeatures" type="int"> +<enum name="PDFFeatures"> <int value="0" label="Loaded Document"/> <int value="1" label="Has Title"/> <int value="2" label="Has Bookmarks"/> </enum> -<enum name="PDFLoadStatus" type="int"> +<enum name="PDFLoadStatus"> <int value="0" label="Loaded a full-page PDF with PDFium"/> <int value="1" label="Loaded an embedded PDF with PDFium"/> <int value="2" label="Showed disabled plugin placeholder for embedded PDF"/> <int value="3" label="Triggered a drive-by download without user gesture"/> </enum> -<enum name="PeerConnectionCounters" type="int"> +<enum name="PeerConnectionCounters"> <int value="0" label="PeerConnection enabled with IPv4."/> <int value="1" label="PeerConnection enabled with Ipv6."/> <int value="2" label="IPv4 BestConnection."/> <int value="3" label="IPv6 BestConnection."/> </enum> -<enum name="PeerConnectionRtcpMux" type="int"> +<enum name="PeerConnectionRtcpMux"> <int value="0" label="Disabled"/> <int value="1" label="Enabled"/> <int value="2" label="No media"/> </enum> -<enum name="PeerConnectionRtcpMuxPolicy" type="int"> +<enum name="PeerConnectionRtcpMuxPolicy"> <int value="0" label="Require"/> <int value="1" label="Negotiate"/> <int value="2" label="Default"/> </enum> -<enum name="PepperInterface" type="int"> +<enum name="PepperInterface"> <!-- Generated by ppapi/tools/pepper_hash_for_uma.cc --> <int value="286711" label="PPB_FlashFullscreen;0.1"/> @@ -28818,7 +28822,7 @@ <int value="2126196629" label="PPB_UDPSocket_Private;0.4"/> </enum> -<enum name="PermissionAction" type="int"> +<enum name="PermissionAction"> <int value="0" label="GRANTED"/> <int value="1" label="DENIED"/> <int value="2" label="DISMISSED"/> @@ -28826,14 +28830,14 @@ <int value="4" label="REVOKED"/> </enum> -<enum name="PermissionEmbargoStatus" type="int"> +<enum name="PermissionEmbargoStatus"> <int value="0" label="NOT_EMBARGOED"/> <int value="1" label="BLACKLISTED"/> <int value="2" label="REPEATED_DISMISSALS"/> <int value="3" label="REPEATED_IGNORES"/> </enum> -<enum name="PermissionRequestType" type="int"> +<enum name="PermissionRequestType"> <int value="0" label="PERMISSION_BUBBLE_UNKNOWN"/> <int value="1" label="PERMISSION_BUBBLE_MULTIPLE"/> <int value="2" label="PERMISSION_BUBBLE_UNUSED_PERMISSION"/> @@ -28852,13 +28856,13 @@ <int value="14" label="PERMISSION_MEDIASTREAM_CAMERA"/> </enum> -<enum name="PermissionStatus" type="int"> +<enum name="PermissionStatus"> <int value="0" label="PERMISSION_STATUS_GRANTED"/> <int value="1" label="PERMISSION_STATUS_DENIED"/> <int value="2" label="PERMISSION_STATUS_ASK"/> </enum> -<enum name="PermissionType" type="int"> +<enum name="PermissionType"> <int value="0" label="PERMISSION_UNKNOWN"/> <int value="1" label="PERMISSION_MIDI_SYSEX"/> <int value="2" label="PERMISSION_PUSH_MESSAGING"/> @@ -28873,7 +28877,7 @@ <int value="11" label="PERMISSION_FLASH"/> </enum> -<enum name="PersistedLogsLogReadStatus" type="int"> +<enum name="PersistedLogsLogReadStatus"> <int value="0" label="RECALL_SUCCESS"/> <int value="1" label="LIST_EMPTY"/> <int value="2" label="LIST_SIZE_MISSING"/> @@ -28886,11 +28890,11 @@ <int value="9" label="DEPRECATED_XML_PROTO_MISMATCH"/> </enum> -<enum name="PersistentAllocatorErrors" type="int"> +<enum name="PersistentAllocatorErrors"> <int value="1" label="Allocator memory is corrupt (set only once)"/> </enum> -<enum name="PersistentHistogramsInitResult" type="int"> +<enum name="PersistentHistogramsInitResult"> <int value="0" label="Local-Memory Success"/> <int value="1" label="Local-Memory Failure"/> <int value="2" label="Mapped-File Success"/> @@ -28899,7 +28903,7 @@ <int value="6" label="No Spare File"/> </enum> -<enum name="PhotoEditorFileType" type="int"> +<enum name="PhotoEditorFileType"> <int value="0" label="jpg"/> <int value="1" label="png"/> <int value="2" label="gif"/> @@ -28908,20 +28912,20 @@ <int value="5" label="other"/> </enum> -<enum name="PhotoEditorLoadMode" type="int"> +<enum name="PhotoEditorLoadMode"> <int value="0" label="From full resolution cache"/> <int value="1" label="From screen resolution cache"/> <int value="2" label="From file"/> <int value="3" label="Other"/> </enum> -<enum name="PhotoEditorSaveResult" type="int"> +<enum name="PhotoEditorSaveResult"> <int value="0" label="Failure"/> <int value="1" label="Success"/> <int value="2" label="Other"/> </enum> -<enum name="PhotoEditorToolType" type="int"> +<enum name="PhotoEditorToolType"> <int value="0" label="Auto-fix"/> <int value="1" label="Crop"/> <int value="2" label="Brightness"/> @@ -28933,14 +28937,14 @@ <int value="8" label="Other"/> </enum> -<enum name="PhotoPickerDialogAction" type="int"> +<enum name="PhotoPickerDialogAction"> <int value="0" label="Cancel"/> <int value="1" label="Photo picked"/> <int value="2" label="New photo"/> <int value="3" label="Use Android picker"/> </enum> -<enum name="PhysicalWebActivityReferer" type="int"> +<enum name="PhysicalWebActivityReferer"> <int value="0" label="REFERER_UNDEFINED"/> <int value="1" label="REFERER_NOTIFICATION (Obsolete)"/> <int value="2" label="REFERER_OPTIN (Obsolete)"/> @@ -28948,7 +28952,7 @@ <int value="4" label="REFERER_DIAGNOSTICS"/> </enum> -<enum name="PhysicalWebInitialStateIosChrome" type="int"> +<enum name="PhysicalWebInitialStateIosChrome"> <int value="0" label="OPTOUT_BTOFF_LOCOFF_UNAUTH"/> <int value="1" label="OPTOUT_BTOFF_LOCOFF_AUTH"/> <int value="2" label="OPTOUT_BTOFF_LOCON_UNAUTH"/> @@ -28975,13 +28979,13 @@ <int value="23" label="ONBOARDING_BTON_LOCON_AUTH"/> </enum> -<enum name="PhysicalWebPreferenceStatus" type="int"> +<enum name="PhysicalWebPreferenceStatus"> <int value="0" label="OFF"/> <int value="1" label="ON"/> <int value="2" label="ONBOARDING"/> </enum> -<enum name="PingResult" type="int"> +<enum name="PingResult"> <int value="0" label="Success"/> <int value="1" label="Response started"/> <int value="2" label="Timed out"/> @@ -28990,7 +28994,7 @@ <int value="5" label="Uncompleted"/> </enum> -<enum name="PipelineStatus" type="int"> +<enum name="PipelineStatus"> <int value="0" label="PIPELINE_OK"/> <int value="1" label="PIPELINE_ERROR_URL_NOT_FOUND"/> <int value="2" label="PIPELINE_ERROR_NETWORK"/> @@ -29013,25 +29017,25 @@ <int value="20" label="AUDIO_RENDERER_ERROR_SPLICE_FAILED"/> </enum> -<enum name="Platform.BootMode.FirmwareWriteProtect" type="int"> +<enum name="Platform.BootMode.FirmwareWriteProtect"> <int value="0" label="Off"/> <int value="1" label="On"/> <int value="2" label="Zero length range"/> <int value="3" label="Error"/> </enum> -<enum name="Platform.BootMode.SwitchStatus" type="int"> +<enum name="Platform.BootMode.SwitchStatus"> <int value="0" label="Off"/> <int value="1" label="On"/> <int value="2" label="Error"/> </enum> -<enum name="Platform.Crouton.Started" type="int"> +<enum name="Platform.Crouton.Started"> <int value="0" label="Total count"/> <int value="1" label="Started"/> </enum> -<enum name="PlatformFileError" type="int"> +<enum name="PlatformFileError"> <int value="0" label="OK"/> <int value="1" label="FAILED"/> <int value="2" label="IN_USE"/> @@ -29051,7 +29055,7 @@ <int value="16" label="I/O"/> </enum> -<enum name="PlatformNotificationStatus" type="int"> +<enum name="PlatformNotificationStatus"> <int value="0" label="OK"/> <int value="1" label="Service Worker not found"/> <int value="2" label="Service Worker error"/> @@ -29059,7 +29063,7 @@ <int value="4" label="Database error"/> </enum> -<enum name="PlatformStateStoreLoadResult" type="int"> +<enum name="PlatformStateStoreLoadResult"> <int value="0" label="SUCCESS"/> <int value="1" label="CLEARED_DATA"> Platform data cleared for new profile. @@ -29075,13 +29079,13 @@ <int value="6" label="PARSE_ERROR">Data could not be parsed.</int> </enum> -<enum name="PluginAvailabilityStatus" type="int"> +<enum name="PluginAvailabilityStatus"> <int value="0" label="PLUGIN_NOT_REGISTERED"/> <int value="1" label="PLUGIN_AVAILABLE"/> <int value="2" label="PLUGIN_DISABLED"/> </enum> -<enum name="PluginGroup" type="int"> +<enum name="PluginGroup"> <int value="0" label="Other Plugin"/> <int value="1" label="Adobe Reader"/> <int value="2" label="Java"/> @@ -29094,7 +29098,7 @@ <int value="9" label="Google Earth"/> </enum> -<enum name="PluginListError" type="int"> +<enum name="PluginListError"> <int value="0" label="NoError"/> <int value="1" label="JsonInvalidEscape"/> <int value="2" label="JsonSyntaxError"/> @@ -29107,7 +29111,7 @@ <int value="9" label="SchemaError"/> </enum> -<enum name="PluginLoadResult" type="int"> +<enum name="PluginLoadResult"> <int value="0" label="LOAD_SUCCESS"/> <int value="1" label="LOAD_FAILED"/> <int value="2" label="ENTRY_POINT_MISSING"/> @@ -29115,7 +29119,7 @@ <int value="4" label="FILE_MISSING"/> </enum> -<enum name="PluginPowerSaverPeripheralHeuristicDecision" type="int"> +<enum name="PluginPowerSaverPeripheralHeuristicDecision"> <int value="0" label="Peripheral"/> <int value="1" label="Essential Same-Origin"/> <int value="2" label="Essential Cross-Origin Big"/> @@ -29124,14 +29128,14 @@ <int value="5" label="Unknown Size"/> </enum> -<enum name="PluginPowerSaverPosterParamPresence" type="int"> +<enum name="PluginPowerSaverPosterParamPresence"> <int value="0" label="No poster param. Plugin power saver disabled."/> <int value="1" label="No poster param. Plugin power saver enabled."/> <int value="2" label="Poster param exists. Plugin power saver disabled."/> <int value="3" label="Poster param exists. Plugin power saver enabled."/> </enum> -<enum name="PluginPowerSaverUnthrottleMethod" type="int"> +<enum name="PluginPowerSaverUnthrottleMethod"> <int value="0" label="Never Unthrottled"/> <int value="1" label="Unthrottled by Click"/> <int value="2" label="Unthrottled by Retroactive Whitelist"/> @@ -29140,7 +29144,7 @@ <int value="5" label="Unthrottled by Omnibox icon"/> </enum> -<enum name="PNaClOptionsOptLevelEnum" type="int"> +<enum name="PNaClOptionsOptLevelEnum"> <int value="0" label="0"/> <int value="1" label="1"/> <int value="2" label="2"/> @@ -29148,12 +29152,12 @@ <int value="4" label="Default / Unknown"/> </enum> -<enum name="PNaClTranslationCacheEnum" type="int"> +<enum name="PNaClTranslationCacheEnum"> <int value="0" label="Miss"/> <int value="1" label="Hit"/> </enum> -<enum name="PointerSensitivity" type="int"> +<enum name="PointerSensitivity"> <int value="1" label="1"/> <int value="2" label="2"/> <int value="3" label="3"/> @@ -29161,13 +29165,13 @@ <int value="5" label="5"/> </enum> -<enum name="PolicyLoadStatus" type="int"> +<enum name="PolicyLoadStatus"> <int value="0" label="Success"/> <int value="1" label="No Policy File"/> <int value="2" label="Load Error"/> </enum> -<enum name="PolicyValidationStatus" type="int"> +<enum name="PolicyValidationStatus"> <int value="0" label="OK"/> <int value="1" label="Bad Initial Signature"/> <int value="2" label="Bad Signature"/> @@ -29182,12 +29186,12 @@ <int value="11" label="Bad Key Validation Signature"/> </enum> -<enum name="Ports" type="int"> +<enum name="Ports"> <int value="80" label="Port 80"/> <int value="443" label="Port 443"/> </enum> -<enum name="PostMergeVerificationOutcome" type="int"> +<enum name="PostMergeVerificationOutcome"> <int value="0" label="Undefined"/> <int value="1" label="Succeeded"/> <int value="2" label="No accounts found"/> @@ -29198,18 +29202,18 @@ <int value="7" label="Overflow"/> </enum> -<enum name="PostSubmitNavigation" type="int"> +<enum name="PostSubmitNavigation"> <int value="0" label="Same domain"/> <int value="1" label="Different domain"/> </enum> -<enum name="PowerBrightnessAdjust" type="int"> +<enum name="PowerBrightnessAdjust"> <int value="0" label="Brightness Down"/> <int value="1" label="Brightness Up"/> <int value="2" label="Brightness Absolute"/> </enum> -<enum name="PowerChargerType" type="int"> +<enum name="PowerChargerType"> <obsolete> Deprecated 11/2014 in issue 427057. </obsolete> @@ -29220,7 +29224,7 @@ <int value="4" label="Safe Spring Charger"/> </enum> -<enum name="PowerConnectedChargingPorts" type="int"> +<enum name="PowerConnectedChargingPorts"> <summary> Connected charging ports on Chrome OS, as reported by the kernel. </summary> @@ -29231,7 +29235,7 @@ <int value="4" label="More than two ports exist"/> </enum> -<enum name="PowerSupplyType" type="int"> +<enum name="PowerSupplyType"> <summary> The type of power supply connected to a Chrome OS system, as reported by the kernel. @@ -29248,7 +29252,7 @@ <int value="9" label="BrickID (Apple)"/> </enum> -<enum name="PowerwashDialogViewType" type="int"> +<enum name="PowerwashDialogViewType"> <int value="0" label="Invoked on settings page"/> <int value="1" label="Shortcut. Confirmation for powerwash only."/> <int value="2" label="Shortcut. Confirmation for powerwash and rollback."/> @@ -29257,12 +29261,12 @@ <int value="5" label="Shortcut. Restart required."/> </enum> -<enum name="PpdSource" type="int"> +<enum name="PpdSource"> <int value="0" label="PPD provided by user"/> <int value="1" label="PPD downloaded from SCS"/> </enum> -<enum name="PrecacheEvents" type="int"> +<enum name="PrecacheEvents"> <int value="0" label="PRECACHE_TASK_STARTED_PERIODIC"/> <int value="1" label="PRECACHE_TASK_STARTED_ONEOFF"/> <int value="2" label="PRECACHE_TASK_STARTED_DUPLICATE"/> @@ -29284,12 +29288,12 @@ <int value="18" label="PRECACHE_SESSION_INCOMPLETE"/> </enum> -<enum name="PreconnectedNavigation" type="int"> +<enum name="PreconnectedNavigation"> <int value="0" label="No recent pre-connect to the page"/> <int value="1" label="Page nav. preceded by a pre-connect"/> </enum> -<enum name="PreconnectMotivation" type="int"> +<enum name="PreconnectMotivation"> <int value="0" label="MOUSE_OVER_MOTIVATED"/> <int value="1" label="PAGE_SCAN_MOTIVATED"/> <int value="2" label="UNIT_TEST_MOTIVATED"/> @@ -29303,24 +29307,24 @@ <int value="10" label="SELF_REFERAL_MOTIVATED"/> </enum> -<enum name="PreconnectSubresourceEval" type="int"> +<enum name="PreconnectSubresourceEval"> <int value="0" label="PRECONNECTION"/> <int value="1" label="PRERESOLUTION"/> <int value="2" label="TOO_NEW"/> </enum> -<enum name="PreconnectTriggerUsed" type="int"> +<enum name="PreconnectTriggerUsed"> <int value="0" label="The pre-connect triggered host was not accessed"/> <int value="1" label="The pre-connect triggered host was accessed"/> </enum> -<enum name="PredictionStatus" type="int"> +<enum name="PredictionStatus"> <int value="0" label="No prediction"/> <int value="1" label="Successful prediction"/> <int value="2" label="Wrong prediction"/> </enum> -<enum name="PrefetchStatus" type="int"> +<enum name="PrefetchStatus"> <int value="0" label="undefined"/> <int value="1" label="success from cache"/> <int value="2" label="success from network"/> @@ -29328,13 +29332,13 @@ <int value="4" label="success already prefetched"/> </enum> -<enum name="PrefHashStoreVersion" type="int"> +<enum name="PrefHashStoreVersion"> <int value="0" label="VERSION_UNINITIALIZED"/> <int value="1" label="VERSION_PRE_MIGRATION"/> <int value="2" label="VERSION_LATEST"/> </enum> -<enum name="PrerenderCookieSendType" type="int"> +<enum name="PrerenderCookieSendType"> <obsolete> Deprecated March 13 2015. </obsolete> @@ -29344,7 +29348,7 @@ <int value="3" label="third party cookies sent for blocking resource"/> </enum> -<enum name="PrerenderCookieStatus" type="int"> +<enum name="PrerenderCookieStatus"> <obsolete> Deprecated March 13 2015. </obsolete> @@ -29367,7 +29371,7 @@ label="[main frame send, main frame change, other send, other change]"/> </enum> -<enum name="PrerenderEvent" type="int"> +<enum name="PrerenderEvent"> <obsolete> Deprecated Dec 12 2014. </obsolete> @@ -29396,7 +29400,7 @@ <int value="22" label="Merge result swapin failed"/> </enum> -<enum name="PrerenderFinalStatus" type="int"> +<enum name="PrerenderFinalStatus"> <int value="0" label="USED"/> <int value="1" label="TIMED_OUT"/> <int value="2" label="EVICTED"/> @@ -29457,7 +29461,7 @@ <int value="57" label="LOW_END_DEVICE"/> </enum> -<enum name="PrerenderHoverEvent" type="int"> +<enum name="PrerenderHoverEvent"> <obsolete> deprecated May 10 2012 </obsolete> @@ -29467,7 +29471,7 @@ <int value="3" label="HOVER_EVENT_CLICK"/> </enum> -<enum name="PrerenderLocalPredictorEvents" type="int"> +<enum name="PrerenderLocalPredictorEvents"> <obsolete> Deprecated April 2015 </obsolete> @@ -29571,7 +29575,7 @@ <int value="95" label="Issue Prerender prefetch issued"/> </enum> -<enum name="PrerenderLocalVisitEvents" type="int"> +<enum name="PrerenderLocalVisitEvents"> <obsolete> Deprecated Nov 16 2012 </obsolete> @@ -29594,7 +29598,7 @@ <int value="19" label="PRERENDER_USED_5"/> </enum> -<enum name="PrerenderMode" type="int"> +<enum name="PrerenderMode"> <obsolete> deprecated Nov 16 2012 </obsolete> @@ -29609,7 +29613,7 @@ <int value="8" label="PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP"/> </enum> -<enum name="PrerenderPageviewEvents" type="int"> +<enum name="PrerenderPageviewEvents"> <obsolete> deprecated Nov 16 2012 </obsolete> @@ -29619,14 +29623,14 @@ <int value="3" label="PAGEVIEW_EVENT_TOP_SITE_LOAD_START"/> </enum> -<enum name="PrerenderRelTypes" type="int"> +<enum name="PrerenderRelTypes"> <int value="0" label="PRERENDER_REL_TYPE_NONE"/> <int value="1" label="PRERENDER_REL_TYPE_PRERENDER"/> <int value="2" label="PRERENDER_REL_TYPE_NEXT"/> <int value="3" label="PRERENDER_REL_TYPE_PRERENDER_AND_NEXT"/> </enum> -<enum name="PrerenderSchemeCancelReason" type="int"> +<enum name="PrerenderSchemeCancelReason"> <int value="0" label="EXTERNAL_PROTOCOL"/> <int value="1" label="DATA"/> <int value="2" label="BLOB"/> @@ -29640,7 +29644,7 @@ <int value="10" label="UNKNOWN"/> </enum> -<enum name="PrerenderTabHelperEvents" type="int"> +<enum name="PrerenderTabHelperEvents"> <obsolete> Deprecated April 2015 </obsolete> @@ -29657,7 +29661,7 @@ <int value="10" label="Login action added, Subframe, pw empty"/> </enum> -<enum name="PresentationResult" type="int"> +<enum name="PresentationResult"> <int value="0" label="Requested"/> <int value="1" label="Success"/> <int value="2" label="SuccessAlreadyPresenting"/> @@ -29673,14 +29677,14 @@ <int value="12" label="RequestDenied"/> </enum> -<enum name="PreTapEvents" type="int"> +<enum name="PreTapEvents"> <int value="0" label="no event"/> <int value="1" label="tapdown"/> <int value="2" label="tapunconfirmed"/> <int value="3" label="tapdown + tapunconfirmed"/> </enum> -<enum name="PreviewsContextMenuActionLoFi" type="int"> +<enum name="PreviewsContextMenuActionLoFi"> <int value="0" label="'Load image' context menu item shown"/> <int value="1" label="'Load image' context menu item clicked"/> <int value="2" @@ -29689,7 +29693,7 @@ <int value="4" label="'Load images' context menu item clicked (obsolete)"/> </enum> -<enum name="PreviewsEligibilityReason" type="int"> +<enum name="PreviewsEligibilityReason"> <int value="0" label="Preview Allowed."/> <int value="1" label="Blacklist not created."/> <int value="2" label="Blacklist data not loaded yet from disk."/> @@ -29703,7 +29707,7 @@ shown on a reload."/> </enum> -<enum name="PreviewsInfoBarAction" type="int"> +<enum name="PreviewsInfoBarAction"> <int value="0" label="Infobar shown"/> <int value="1" label="Infobar 'Load original' clicked"/> <int value="2" label="Infobar dismissed by user"/> @@ -29712,12 +29716,12 @@ <int value="5" label="Infobar dismissed by tab closure"/> </enum> -<enum name="PreviewsUserOptedOut" type="int"> +<enum name="PreviewsUserOptedOut"> <int value="0" label="The user did not choose to reload the full page."/> <int value="1" label="The user chose to reload the full page."/> </enum> -<enum name="PrinterProtocol" type="int"> +<enum name="PrinterProtocol"> <int value="0" label="Unknown"/> <int value="1" label="Universal Serial Bus (usb)"/> <int value="2" label="Internet Print Protocol (ipp)"/> @@ -29728,7 +29732,7 @@ <int value="7" label="Line Print Daemon (lpd)"/> </enum> -<enum name="PrinterServiceEventType" type="int"> +<enum name="PrinterServiceEventType"> <int value="0" label="Printer added"/> <int value="1" label="Page displayed (Deprecated)"/> <int value="2" label="Printer supported notification shown"/> @@ -29736,7 +29740,7 @@ <int value="4" label="Printer provider Web Store app launched"/> </enum> -<enum name="PrinterSetupResult" type="int"> +<enum name="PrinterSetupResult"> <int value="0" label="Fatal Error"/> <int value="1" label="Success"/> <int value="2" label="Printer Unreachable"/> @@ -29747,7 +29751,7 @@ <int value="13" label="Failed to download PPD"/> </enum> -<enum name="PrintJobResult" type="int"> +<enum name="PrintJobResult"> <int value="0" label="Unknown"/> <int value="1" label="Successful Finish"/> <int value="2" label="Cancelled due to timeout"/> @@ -29755,7 +29759,7 @@ <int value="4" label="Lost track of job"/> </enum> -<enum name="PrintPreviewFailureType" type="int"> +<enum name="PrintPreviewFailureType"> <int value="0" label="No error"/> <int value="1" label="Bad settings from print preview tab"/> <int value="2" label="Copy metadata failed (Deprecated)"/> @@ -29767,7 +29771,7 @@ <int value="8" label="Received bad printer settings"/> </enum> -<enum name="PrintPreviewFontTypeType" type="int"> +<enum name="PrintPreviewFontTypeType"> <int value="0" label="TYPE1"/> <int value="1" label="TYPE1_CID"/> <int value="2" label="CFF"/> @@ -29776,20 +29780,20 @@ <int value="5" label="NOT_EMBEDDABLE"/> </enum> -<enum name="PrintPreviewGcpPromoBuckets" type="int"> +<enum name="PrintPreviewGcpPromoBuckets"> <int value="0" label="PROMO_SHOWN"/> <int value="1" label="PROMO_CLICKED"/> <int value="2" label="PROMO_CLOSED"/> </enum> -<enum name="PrintPreviewHelperEvents" type="int"> +<enum name="PrintPreviewHelperEvents"> <int value="0" label="PREVIEW_EVENT_REQUESTED"/> <int value="1" label="PREVIEW_EVENT_CACHE_HIT"/> <int value="2" label="PREVIEW_EVENT_CREATE_DOCUMENT"/> <int value="3" label="PREVIEW_EVENT_NEW_SETTINGS"/> </enum> -<enum name="PrintPreviewPrintDestinationBuckets" type="int"> +<enum name="PrintPreviewPrintDestinationBuckets"> <int value="0" label="DESTINATION_SHOWN"/> <int value="1" label="DESTINATION_CLOSED_CHANGED"/> <int value="2" label="DESTINATION_CLOSED_UNCHANGED"/> @@ -29806,12 +29810,12 @@ <int value="13" label="INVITATION_REJECTED"/> </enum> -<enum name="PrintPreviewPrintDocumentTypeBuckets" type="int"> +<enum name="PrintPreviewPrintDocumentTypeBuckets"> <int value="0" label="HTML_DOCUMENT"/> <int value="1" label="PDF_DOCUMENT"/> </enum> -<enum name="PrintPreviewPrintSettingsUiBuckets" type="int"> +<enum name="PrintPreviewPrintSettingsUiBuckets"> <int value="0" label="ADVANCED_SETTINGS_DIALOG_SHOWN"/> <int value="1" label="ADVANCED_SETTINGS_DIALOG_CANCELED"/> <int value="2" label="MORE_SETTINGS_CLICKED"/> @@ -29820,7 +29824,7 @@ <int value="5" label="PRINT_WITH_SETTINGS_COLLAPSED"/> </enum> -<enum name="PrintPreviewUserActionType" type="int"> +<enum name="PrintPreviewUserActionType"> <int value="0" label="PRINT_TO_PRINTER"/> <int value="1" label="PRINT_TO_PDF"/> <int value="2" label="CANCEL"/> @@ -29834,7 +29838,7 @@ <int value="10" label="PRINT_WITH_EXTENSION"/> </enum> -<enum name="PrintSettings" type="int"> +<enum name="PrintSettings"> <int value="0" label="LANDSCAPE"/> <int value="1" label="PORTRAIT"/> <int value="2" label="COLOR"/> @@ -29857,7 +29861,7 @@ <int value="19" label="PRINT_AS_IMAGE"/> </enum> -<enum name="PrivetNotificationsEvent" type="int"> +<enum name="PrivetNotificationsEvent"> <int value="0" label="PRIVET_SERVICE_STARTED"/> <int value="1" label="PRIVET_LISTER_STARTED"/> <int value="2" label="PRIVET_DEVICE_CHANGED"/> @@ -29868,7 +29872,7 @@ <int value="7" label="PRIVET_DISABLE_NOTIFICATIONS_CLICKED"/> </enum> -<enum name="ProcessDetailedExitStatus" type="int"> +<enum name="ProcessDetailedExitStatus"> <int value="0" label="Empty minidump in running app"/> <int value="1" label="Empty minidump in paused app"/> <int value="2" label="Empty minidump in background app"/> @@ -29877,7 +29881,7 @@ <int value="5" label="Valid minidump in background app"/> </enum> -<enum name="ProcessNameHash" type="int"> +<enum name="ProcessNameHash"> <summary> The hash of a lower case process name generated using metrics::HashName. </summary> @@ -29934,7 +29938,7 @@ <int value="2011028983" label="pcman.exe"/> </enum> -<enum name="ProcessType" type="int"> +<enum name="ProcessType"> <obsolete> Deprecated 3/2013. No longer generated. </obsolete> @@ -29957,7 +29961,7 @@ <int value="13" label="PPAPI_PLUGIN_PROCESS"/> </enum> -<enum name="ProcessType2" type="int"> +<enum name="ProcessType2"> <summary> The value for type comes from the ProcessType enum in content/public/common/process_type.h. @@ -29978,7 +29982,7 @@ <int value="14" label="NACL_BROKER_PROCESS"/> </enum> -<enum name="ProfileAddNewUser" type="int"> +<enum name="ProfileAddNewUser"> <int value="0" label="Add new user from icon menu"/> <int value="1" label="Add new user from title bar menu"/> <int value="2" label="Add new user from settings dialog"/> @@ -29986,7 +29990,7 @@ <int value="4" label="Auto-created after deleting last user"/> </enum> -<enum name="ProfileAndroidAccountManagementMenu" type="int"> +<enum name="ProfileAndroidAccountManagementMenu"> <int value="0" label="Opened Menu"> User arrived at the Account management screen. </int> @@ -30013,7 +30017,7 @@ </int> </enum> -<enum name="ProfileAuth" type="int"> +<enum name="ProfileAuth"> <int value="0" label="Authentication was unnecessary (profile not locked)"/> <int value="1" label="Authentication performed using local credentials"/> <int value="2" label="Authentication performed on-line"/> @@ -30021,7 +30025,7 @@ <int value="4" label="Authentication failed due to being offline"/> </enum> -<enum name="ProfileAvatar" type="int"> +<enum name="ProfileAvatar"> <int value="0" label="Generic"/> <int value="1" label="Generic Aqua"/> <int value="2" label="Generic Blue"/> @@ -30053,7 +30057,7 @@ <int value="28" label="GAIA"/> </enum> -<enum name="ProfileCreateResult" type="int"> +<enum name="ProfileCreateResult"> <int value="0" label="Failed locally"/> <int value="1" label="Failed remotely"/> <int value="2" label="Created but not initialized (should never happen)"/> @@ -30061,7 +30065,7 @@ <int value="4" label="Canceled"/> </enum> -<enum name="ProfileDeleteAction" type="int"> +<enum name="ProfileDeleteAction"> <int value="0" label="Settings Page"> The user confirmed deletion of a profile from the settings page. This metric is recorded even if profile deletion is cancelled after the confirmation. @@ -30087,7 +30091,7 @@ </int> </enum> -<enum name="ProfileDesktopMenu" type="int"> +<enum name="ProfileDesktopMenu"> <int value="0" label="Locked in Menu"> User opened the user menu, and clicked lock. </int> @@ -30111,7 +30115,7 @@ </int> </enum> -<enum name="ProfileErrorType" type="int"> +<enum name="ProfileErrorType"> <int value="0" label="History error"/> <int value="1" label="Preferences error"/> <int value="2" label="Webdata autofill DB error"/> @@ -30121,12 +30125,12 @@ <int value="8" label="Payment manifest DB error"/> </enum> -<enum name="ProfileGaiaPhotoOptions" type="int"> +<enum name="ProfileGaiaPhotoOptions"> <int value="0" label="User opted to use GAIA photo"/> <int value="1" label="User opted not to use GAIA photo"/> </enum> -<enum name="ProfileImageDownloadResult" type="int"> +<enum name="ProfileImageDownloadResult"> <int value="0" label="DownloadSuccessChanged"> <summary> Reported when image download succeeds and the image is newer than what we @@ -30146,12 +30150,12 @@ </int> </enum> -<enum name="ProfileNetUserCount" type="int"> +<enum name="ProfileNetUserCount"> <int value="0" label="Added new user"/> <int value="1" label="Deleted a profile"/> </enum> -<enum name="ProfileNewAvatarMenuNotYou" type="int"> +<enum name="ProfileNewAvatarMenuNotYou"> <int value="0" label="View 'Not You?' Bubble"> User views the 'Not You?' bubble. </int> @@ -30166,7 +30170,7 @@ </int> </enum> -<enum name="ProfileNewAvatarMenuSignin" type="int"> +<enum name="ProfileNewAvatarMenuSignin"> <int value="0" label="View Signin Bubble"> User viewed the signin bubble after successfully using the inline signin. </int> @@ -30178,7 +30182,7 @@ </int> </enum> -<enum name="ProfileNewAvatarMenuUpgrade" type="int"> +<enum name="ProfileNewAvatarMenuUpgrade"> <int value="0" label="View Upgrade Bubble"> User views the upgrade bubble. </int> @@ -30191,7 +30195,7 @@ </int> </enum> -<enum name="ProfileOpen" type="int"> +<enum name="ProfileOpen"> <int value="0" label="Add new user"/> <int value="1" label="Add new user from icon menu"/> <int value="2" label="Add new user from title bar menu"/> @@ -30202,7 +30206,7 @@ <int value="7" label="Deleted a profile"/> </enum> -<enum name="ProfileOpenMethod" type="int"> +<enum name="ProfileOpenMethod"> <int value="0" label="Opened the avatar menu from NTP"/> <int value="1" label="Opened the avatar menu from avatar button"/> <int value="2" label="Switch to profile from icon menu"/> @@ -30215,7 +30219,7 @@ <int value="9" label="Switch to profile from context menu"/> </enum> -<enum name="ProfileResetRequestOriginEnum" type="int"> +<enum name="ProfileResetRequestOriginEnum"> <int value="0" label="Unspecified"/> <int value="1" label="Unknown"/> <int value="2" label="User click"/> @@ -30223,7 +30227,7 @@ <int value="4" label="Triggered reset"/> </enum> -<enum name="ProfileSigninStatus" type="int"> +<enum name="ProfileSigninStatus"> <int value="0" label="All profiles signed in"/> <int value="1" label="All profiles not signed in"/> <int value="2" label="Mixed signin status"/> @@ -30231,7 +30235,7 @@ <int value="4" label="Error getting signin status"/> </enum> -<enum name="ProfileSync" type="int"> +<enum name="ProfileSync"> <int value="0" label="Signed in to sync"/> <int value="1" label="Signed in to sync from original profile"/> <int value="2" label="Signed in to sync from secondary profile"/> @@ -30241,19 +30245,19 @@ <int value="6" label="Selected a passphrase"/> </enum> -<enum name="ProfileSyncCustomize" type="int"> +<enum name="ProfileSyncCustomize"> <int value="0" label="Customized sync options"/> <int value="1" label="Chose what to sync"/> <int value="2" label="Encrypted all data"/> <int value="3" label="Selected a passphrase"/> </enum> -<enum name="ProfileType" type="int"> +<enum name="ProfileType"> <int value="0" label="Original (default) profile"/> <int value="1" label="Secondary (user-created) profile"/> </enum> -<enum name="ProfileUpgradeEnrollment" type="int"> +<enum name="ProfileUpgradeEnrollment"> <int value="0" label="User viewed the Upgrade promo card in the user menu."/> <int value="1" label="User selected to view the intro tutorial."/> <int value="2" label="User opted into New Profile Management by Promo card."/> @@ -30262,7 +30266,7 @@ <int value="5" label="User elected to send feedback."/> </enum> -<enum name="ProtectorError" type="int"> +<enum name="ProtectorError"> <obsolete> Deprecated 8/2013. No longer generated. </obsolete> @@ -30276,7 +30280,7 @@ <int value="3" label="Value is valid and zero"/> </enum> -<enum name="ProtocolVersion" type="int"> +<enum name="ProtocolVersion"> <int value="0" label="UNKNOWN"/> <int value="1" label="HTTP 1.1"/> <int value="2" label="SPDY 2.0"/> @@ -30285,7 +30289,7 @@ <int value="5" label="SPDY 4.0"/> </enum> -<enum name="ProvisionalLoadEvent" type="int"> +<enum name="ProvisionalLoadEvent"> <int value="0" label="Stopped no error"> This should represent the provisional load being stopped by the user, but should not occur pre-PlzNavigate. @@ -30301,7 +30305,7 @@ <int value="3" label="Load successfully committed"/> </enum> -<enum name="ProvisionalSaveFailure" type="int"> +<enum name="ProvisionalSaveFailure"> <int value="0" label="SAVING_DISABLED"/> <int value="1" label="EMPTY_PASSWORD"/> <int value="2" label="NO_MATCHING_FORM"/> @@ -30312,7 +30316,7 @@ <int value="7" label="SYNC_CREDENTIALS"/> </enum> -<enum name="ProxyStatus" type="int"> +<enum name="ProxyStatus"> <int value="0" label="PROXY_STATUS_IGNORED"/> <int value="1" label="PROXY_UNINITIALIZED"/> <int value="2" label="PROXY_NOT_USED"/> @@ -30320,7 +30324,7 @@ <int value="4" label="PROXY_HAS_RULES"/> </enum> -<enum name="PublicKeyPinFailedDomain" type="int"> +<enum name="PublicKeyPinFailedDomain"> <int value="0" label="DOMAIN_NOT_PINNED"/> <int value="1" label="DOMAIN_GOOGLE_COM"/> <int value="2" label="DOMAIN_ANDROID_COM"/> @@ -30578,7 +30582,7 @@ <int value="254" label="DOMAIN_SPIDEROAK_COM"/> </enum> -<enum name="PushDeliveryStatus" type="int"> +<enum name="PushDeliveryStatus"> <int value="0" label="Successful"/> <int value="1" label="Message was invalid"/> <int value="2" label="App id was unknown"/> @@ -30589,7 +30593,7 @@ <int value="7" label="Service Worker timeout while processing event"/> </enum> -<enum name="PushGetRegistrationStatus" type="int"> +<enum name="PushGetRegistrationStatus"> <int value="0" label="Successful"/> <int value="1" label="No push service"/> <int value="2" label="Storage error"/> @@ -30601,7 +30605,7 @@ <int value="8" label="No live Service Worker"/> </enum> -<enum name="PushRegistrationStatus" type="int"> +<enum name="PushRegistrationStatus"> <int value="0" label="Successful - from push service"/> <int value="1" label="Service Worker not found"/> <int value="2" label="No push service"/> @@ -30620,7 +30624,7 @@ <int value="15" label="Renderer shutdown"/> </enum> -<enum name="PushUnregistrationReason" type="int"> +<enum name="PushUnregistrationReason"> <int value="0" label="Unknown"/> <int value="1" label="unsubscribe() JavaScript API"/> <int value="2" label="Permission revoked"/> @@ -30633,7 +30637,7 @@ <int value="9" label="getSubscription() storage corrupt"/> </enum> -<enum name="PushUnregistrationStatus" type="int"> +<enum name="PushUnregistrationStatus"> <int value="0" label="Successful - from push service"/> <int value="1" label="Successful - was not registered"/> <int value="2" label="Pending - will retry network error"/> @@ -30644,7 +30648,7 @@ <int value="7" label="Network error"/> </enum> -<enum name="PushUserVisibleStatus" type="int"> +<enum name="PushUserVisibleStatus"> <int value="0" label="Required and shown"/> <int value="1" label="Not required but shown"/> <int value="2" label="Not required and not shown"/> @@ -30652,7 +30656,7 @@ <int value="4" label="Required but not shown - grace exceeded"/> </enum> -<enum name="QuicAddressMismatch" type="int"> +<enum name="QuicAddressMismatch"> <int value="0" label="Address mismatch: IPv4 IPv4"/> <int value="1" label="Address mismatch: IPv6 IPv6"/> <int value="2" label="Address mismatch: IPv4 IPv6"/> @@ -30663,13 +30667,13 @@ <int value="7" label="Address and port match: IPv6 IPv6"/> </enum> -<enum name="QuicAlternativeProxyUsage" type="int"> +<enum name="QuicAlternativeProxyUsage"> <int value="0" label="ALTERNATIVE_PROXY_USAGE_NO_RACE"/> <int value="1" label="ALTERNATIVE_PROXY_USAGE_WON_RACE"/> <int value="2" label="ALTERNATIVE_PROXY_USAGE_LOST_RACE"/> </enum> -<enum name="QuicBadPacketLossEvents" type="int"> +<enum name="QuicBadPacketLossEvents"> <int value="1" label="ONE_PACKET_LOST"/> <int value="2" label="TWO_PACKETS_LOST"/> <int value="3" label="THREE_PACKETS_LOST"/> @@ -30677,7 +30681,7 @@ <int value="5" label="FIVE_PACKETS_LOST"/> </enum> -<enum name="QuicConnectionMigrationStatus" type="int"> +<enum name="QuicConnectionMigrationStatus"> <int value="0" label="NO_MIGRATABLE_STREAMS"/> <int value="1" label="ALREADY_MIGRATED"/> <int value="2" label="INTERNAL_ERROR"/> @@ -30688,13 +30692,13 @@ <int value="7" label="MIGRATION_STATUS_NO_ALTERNATE_NETWORK"/> </enum> -<enum name="QuicDisabledReason" type="int"> +<enum name="QuicDisabledReason"> <int value="1" label="Public reset post handshake"/> <int value="2" label="Timeout with open streams"/> <int value="3" label="Bad packet loss rate"/> </enum> -<enum name="QuicDiskCacheAPICall" type="int"> +<enum name="QuicDiskCacheAPICall"> <int value="0" label="Start"/> <int value="1" label="WaitForDataReady"/> <int value="2" label="Parse"/> @@ -30705,12 +30709,12 @@ <int value="7" label="ResetWaitForDataReady"/> </enum> -<enum name="QuicDiskCacheEntryState" type="int"> +<enum name="QuicDiskCacheEntryState"> <int value="0" label="Opened"/> <int value="1" label="Closed"/> </enum> -<enum name="QuicDiskCacheFailureReason" type="int"> +<enum name="QuicDiskCacheFailureReason"> <int value="0" label="WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE"/> <int value="1" label="GET_BACKEND_FAILURE"/> <int value="2" label="OPEN_FAILURE"/> @@ -30725,7 +30729,7 @@ <int value="11" label="PARSE_DATA_DECODE_FAILURE"/> </enum> -<enum name="QuicErrorCodes" type="int"> +<enum name="QuicErrorCodes"> <int value="0" label="NO_ERROR"/> <int value="1" label="INTERNAL_ERROR"/> <int value="2" label="STREAM_DATA_AFTER_TERMINATION"/> @@ -30826,20 +30830,20 @@ <int value="97" label="HEADERS_STREAM_DATA_DECOMPRESS_FAILURE"/> </enum> -<enum name="QuicHandshakeFailureReason" type="int"> +<enum name="QuicHandshakeFailureReason"> <int value="0" label="UNKNOWN"/> <int value="1" label="BLACK_HOLE"/> <int value="2" label="PUBLIC_RESET"/> </enum> -<enum name="QuicHandshakeState" type="int"> +<enum name="QuicHandshakeState"> <int value="0" label="STARTED"/> <int value="1" label="ENCRYPTION_ESTABLISHED"/> <int value="2" label="HANDSHAKE_CONFIRMED"/> <int value="3" label="FAILED"/> </enum> -<enum name="QuickofficeErrorTypes" type="int"> +<enum name="QuickofficeErrorTypes"> <int value="0" label="doc uncaught js exception"/> <int value="1" label="docx uncaught js exception"/> <int value="2" label="docm uncaught js exception"/> @@ -30926,7 +30930,7 @@ <int value="83" label="ppsm editing dom sync error"/> </enum> -<enum name="QuickofficeFileFormat" type="int"> +<enum name="QuickofficeFileFormat"> <int value="0" label="doc"/> <int value="1" label="docx"/> <int value="2" label="docm"/> @@ -30942,7 +30946,7 @@ <int value="12" label="csv"/> </enum> -<enum name="QuicRejectReasons" type="int"> +<enum name="QuicRejectReasons"> <int value="1" label="CLIENT_NONCE_UNKNOWN_FAILURE"/> <int value="2" label="CLIENT_NONCE_INVALID_FAILURE"/> <int value="4" label="CLIENT_NONCE_NOT_UNIQUE_FAILURE"/> @@ -30986,7 +30990,7 @@ label="INVALID_EXPECTED_LEAF_CERTIFICATE+SERVER_NONCE_REQUIRED_FAILURE+SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE"/> </enum> -<enum name="QuicRstStreamErrorCodes" type="int"> +<enum name="QuicRstStreamErrorCodes"> <int value="0" label="NO_ERROR"/> <int value="1" label="ERROR_PROCESSING_STREAM"/> <int value="2" label="MULTIPLE_TERMINATION_OFFSETS"/> @@ -31005,7 +31009,7 @@ <int value="15" label="HEADERS_TOO_LARGE"/> </enum> -<enum name="QuicServerConfigState" type="int"> +<enum name="QuicServerConfigState"> <int value="0" label="SERVER_CONFIG_EMPTY"/> <int value="1" label="SERVER_CONFIG_INVALID"/> <int value="2" label="SERVER_CONFIG_CORRUPTED"/> @@ -31014,14 +31018,14 @@ <int value="5" label="SERVER_CONFIG_VALID"/> </enum> -<enum name="QuicSessionErrorCodes" type="int"> +<enum name="QuicSessionErrorCodes"> <int value="0" label="CONNECTING_SOCKET"/> <int value="1" label="SETTING_RECEIVE_BUFFER"/> <int value="2" label="SETTING_SEND_BUFFER"/> <int value="3" label="SETTING_DO_NOT_FRAGMENT"/> </enum> -<enum name="QuicSessionLocations" type="int"> +<enum name="QuicSessionLocations"> <int value="0" label="DESTRUCTOR"/> <int value="1" label="ADD_OBSERVER"/> <int value="2" label="TRY_CREATE_STREAM"/> @@ -31030,7 +31034,7 @@ <int value="5" label="NOTIFY_FACTORY_OF_SESSION_CLOSED"/> </enum> -<enum name="QuotaOriginTypes" type="int"> +<enum name="QuotaOriginTypes"> <int value="0" label="Other"/> <int value="1" label="None"/> <int value="2" label="google.com durable"/> @@ -31040,7 +31044,7 @@ <int value="6" label="In use"/> </enum> -<enum name="RankerModelStatus" type="int"> +<enum name="RankerModelStatus"> <int value="0" label="OK"/> <int value="1" label="Download Throttled"/> <int value="2" label="Download Failed"/> @@ -31051,19 +31055,19 @@ <int value="7" label="Model Loading Abandoned"/> </enum> -<enum name="RapporDiscardReason" type="int"> +<enum name="RapporDiscardReason"> <int value="0" label="Upload Success"/> <int value="1" label="Upload Rejected"/> <int value="2" label="Queue Overflowed"/> </enum> -<enum name="RapporLoadResultType" type="int"> +<enum name="RapporLoadResultType"> <int value="0" label="LOAD_SUCCESS"/> <int value="1" label="LOAD_EMPTY_VALUE"/> <int value="2" label="LOAD_CORRUPT_VALUE"/> </enum> -<enum name="ReadingListContextMenuActions" type="int"> +<enum name="ReadingListContextMenuActions"> <int value="0" label="New Tab"/> <int value="1" label="New Incognito Tab"/> <int value="2" label="Copy Link"/> @@ -31071,20 +31075,20 @@ <int value="4" label="Cancel"/> </enum> -<enum name="ReadingListDownloadStatus" type="int"> +<enum name="ReadingListDownloadStatus"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Will retry"/> </enum> -<enum name="RecentTabsAction" type="int"> +<enum name="RecentTabsAction"> <int value="0" label="Local Session Tab"/> <int value="1" label="Other Device Tab"/> <int value="2" label="Restore Window"/> <int value="3" label="Show More"/> </enum> -<enum name="RecoveryComponentEvent" type="int"> +<enum name="RecoveryComponentEvent"> <int value="0" label="RunningNonElevated"/> <int value="1" label="ElevationNeeded"/> <int value="2" label="RunFailed"/> @@ -31097,12 +31101,12 @@ <int value="9" label="DownloadError"/> </enum> -<enum name="RefcountOperation" type="int"> +<enum name="RefcountOperation"> <int value="0" label="Decrement"/> <int value="1" label="Increment"/> </enum> -<enum name="RemoteHungProcessTerminateReason" type="int"> +<enum name="RemoteHungProcessTerminateReason"> <int value="1" label="Terminate accepted by user"/> <int value="2" label="No visible windows found"/> <int value="3" label="Retry attempts to notify remote process exceeded"/> @@ -31110,13 +31114,13 @@ <int value="5" label="Failed to read ACK message from socket"/> </enum> -<enum name="RemotePlaybackDeviceType" type="int"> +<enum name="RemotePlaybackDeviceType"> <int value="0" label="Cast Generic Media Player"/> <int value="1" label="Cast YouTube Player"/> <int value="2" label="Non-Cast YouTube Player"/> </enum> -<enum name="RemotePlaybackUrlResolveResult" type="int"> +<enum name="RemotePlaybackUrlResolveResult"> <int value="0" label="Successfully Resolved"/> <int value="1" label="Malformed or empty Url"/> <int value="2" label="No CORS header when required"/> @@ -31126,7 +31130,7 @@ <int value="6" label="Unknown media type"/> </enum> -<enum name="RemoteProcessInteractionResult" type="int"> +<enum name="RemoteProcessInteractionResult"> <int value="0" label="Terminate succeeded"/> <int value="1" label="Terminate failed"/> <int value="2" label="Remote process not found"/> @@ -31145,7 +31149,7 @@ <int value="13" label="Orphaned lock file"/> </enum> -<enum name="RemotingStartTrigger" type="int"> +<enum name="RemotingStartTrigger"> <int value="0" label="Unknown start trigger"/> <int value="1" label="Entered fullscreen"/> <int value="2" label="Became dominant content"/> @@ -31158,7 +31162,7 @@ <int value="9" label="CDM ready"/> </enum> -<enum name="RemotingStopTrigger" type="int"> +<enum name="RemotingStopTrigger"> <int value="0" label="Unknown stop trigger"/> <int value="1" label="Route terminated"/> <int value="2" label="Media element destroyed"/> @@ -31180,14 +31184,14 @@ <int value="18" label="Mojo pipe error"/> </enum> -<enum name="RemotingTrackConfiguration" type="int"> +<enum name="RemotingTrackConfiguration"> <int value="0" label="None"/> <int value="1" label="Audio only"/> <int value="2" label="Video only"/> <int value="3" label="Audio and video"/> </enum> -<enum name="RendererSchedulerTaskQueueType" type="int"> +<enum name="RendererSchedulerTaskQueueType"> <int value="0" label="Control"/> <int value="1" label="Default"/> <int value="2" label="DefaultLoading"/> @@ -31201,12 +31205,12 @@ <int value="10" label="Test"/> </enum> -<enum name="RendererType" type="int"> +<enum name="RendererType"> <int value="1" label="Normal renderer"/> <int value="2" label="Extension renderer"/> </enum> -<enum name="RendererUnresponsiveType" type="int"> +<enum name="RendererUnresponsiveType"> <obsolete> Deprecated 3/2017. </obsolete> @@ -31219,7 +31223,7 @@ <int value="6" label="While closing the page"/> </enum> -<enum name="RenderViewContextMenuItem" type="int"> +<enum name="RenderViewContextMenuItem"> <int value="0" label="IDC_CONTENT_CONTEXT_CUSTOM_FIRST"/> <int value="1" label="IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST"/> <int value="2" label="IDC_CONTENT_CONTEXT_PROTOCOL_HANDLER_FIRST"/> @@ -31311,7 +31315,7 @@ <int value="88" label="IDC_CONTENT_CONTEXT_EXIT_FULLSCREEN"/> </enum> -<enum name="ReportProcessingResult" type="int"> +<enum name="ReportProcessingResult"> <int value="0" label="Success">A report was created and uploaded</int> <int value="1" label="Suppressed"> A report was not uploaded because the CSD Whitelist killswitch was present @@ -31331,7 +31335,7 @@ </int> </enum> -<enum name="RequestAction" type="int"> +<enum name="RequestAction"> <int value="0" label="CANCEL"/> <int value="1" label="REDIRECT"/> <int value="2" label="MODIFY_REQUEST_HEADERS"/> @@ -31339,7 +31343,7 @@ <int value="4" label="SET_AUTH_CREDENTIALS"/> </enum> -<enum name="RequestedImageMimeType" type="int"> +<enum name="RequestedImageMimeType"> <int value="0" label="Png"/> <int value="1" label="Jpeg"/> <int value="2" label="Webp"/> @@ -31350,7 +31354,7 @@ <int value="7" label="Unknown"/> </enum> -<enum name="RequestedWindowState" type="int"> +<enum name="RequestedWindowState"> <int value="0" label="Invalid"/> <int value="1" label="Normal window state"/> <int value="2" label="Minimized window state"/> @@ -31359,19 +31363,19 @@ <int value="5" label="Docked window state"/> </enum> -<enum name="RequestMediaKeySystemAccessStatus" type="int"> +<enum name="RequestMediaKeySystemAccessStatus"> <int value="0" label="Requested"/> <int value="1" label="Supported"/> </enum> -<enum name="ResolutionCategory" type="int"> +<enum name="ResolutionCategory"> <int value="0" label="RESOLVE_SUCCESS"/> <int value="1" label="RESOLVE_FAIL"/> <int value="2" label="RESOLVE_SPECULATIVE_SUCCESS"/> <int value="3" label="RESOLVE_SPECULATIVE_FAIL"/> </enum> -<enum name="ResolutionUnspecWasteCategory" type="int"> +<enum name="ResolutionUnspecWasteCategory"> <int value="0" label="AF_WASTE_IPV4_ONLY"> Running in a IPv4-only configuration. No waste. </int> @@ -31395,12 +31399,12 @@ </int> </enum> -<enum name="ResourceHasClient" type="int"> +<enum name="ResourceHasClient"> <int value="0" label="No client"/> <int value="1" label="Has client"/> </enum> -<enum name="ResourceLoaderExpectedContentSizeResult" type="int"> +<enum name="ResourceLoaderExpectedContentSizeResult"> <int value="0" label="EQ_RESPONSE_BODY"/> <int value="1" label="EQ_RESPONSE_BODY_GT_EQ_BUFFER_SIZE"/> <int value="2" label="GT_EQ_BUFFER_SIZE"/> @@ -31409,7 +31413,7 @@ <int value="5" label="UNKNOWN"/> </enum> -<enum name="ResourceLoaderInliningStatus" type="int"> +<enum name="ResourceLoaderInliningStatus"> <int value="0" label="Applicable"/> <int value="1" label="EarlyAllocation"/> <int value="2" label="UnknownContentLength"/> @@ -31418,7 +31422,7 @@ <int value="5" label="HasContentEncoding"/> </enum> -<enum name="ResourcePrefetchPredictorMainFrameRequestStats" type="int"> +<enum name="ResourcePrefetchPredictorMainFrameRequestStats"> <int value="0" label="MAIN_FRAME_REQUEST_STATS_TOTAL_REQUESTS"/> <int value="1" label="MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS"/> <int value="2" label="MAIN_FRAME_REQUEST_STATS_TOTAL_REDIRECTS"/> @@ -31427,7 +31431,7 @@ <int value="5" label="MAIN_FRAME_REQUEST_STATS_PROCESSED_RESPONSES"/> </enum> -<enum name="ResourcePrefetchPredictorNavigationEvent" type="int"> +<enum name="ResourcePrefetchPredictorNavigationEvent"> <int value="0" label="NAVIGATION_EVENT_REQUEST_STARTED"/> <int value="1" label="NAVIGATION_EVENT_REQUEST_REDIRECTED"/> <int value="2" label="NAVIGATION_EVENT_REQUEST_REDIRECTED_EMPTY_URL"/> @@ -31444,13 +31448,13 @@ <int value="13" label="NAVIGATION_EVENT_NO_PREDICTIONS_FOR_URL"/> </enum> -<enum name="ResourcePrefetchPredictorNavigationStatus" type="int"> +<enum name="ResourcePrefetchPredictorNavigationStatus"> <int value="0" label="NAVIGATION_STATUS_COMPLETE"/> <int value="1" label="NAVIGATION_STATUS_COMPLETE_ABANDONED"/> <int value="2" label="NAVIGATION_STATUS_ABANDONED"/> </enum> -<enum name="ResourcePrefetchPredictorNetworkType" type="int"> +<enum name="ResourcePrefetchPredictorNetworkType"> <int value="-2" label="CONNECTION_ALL"/> <int value="-1" label="CONNECTION_CELLULAR"/> <int value="0" label="CONNECTION_UNKNOWN"/> @@ -31463,7 +31467,7 @@ <int value="7" label="CONNECTION_BLUETOOTH"/> </enum> -<enum name="ResourcePrefetchPredictorRedirectStatus" type="int"> +<enum name="ResourcePrefetchPredictorRedirectStatus"> <int value="0" label="NO_REDIRECT"/> <int value="1" label="NO_REDIRECT_BUT_PREDICTED"/> <int value="2" label="REDIRECT_NOT_PREDICTED"/> @@ -31471,19 +31475,19 @@ <int value="4" label="REDIRECT_CORRECTLY_PREDICTED"/> </enum> -<enum name="ResourcePrefetchPredictorReportingEvent" type="int"> +<enum name="ResourcePrefetchPredictorReportingEvent"> <int value="0" label="REPORTING_EVENT_ALL_HISTORY_CLEARED"/> <int value="1" label="REPORTING_EVENT_PARTIAL_HISTORY_CLEARED"/> </enum> -<enum name="ResourcePrefetchPredictorRequestStats" type="int"> +<enum name="ResourcePrefetchPredictorRequestStats"> <int value="0" label="REQUEST_STATS_TOTAL_RESPONSES"/> <int value="1" label="REQUEST_STATS_TOTAL_PROCESSED_RESPONSES"/> <int value="2" label="REQUEST_STATS_NO_RESOURCE_REQUEST_INFO"/> <int value="3" label="REQUEST_STATS_NO_RENDER_VIEW_ID_FROM_REQUEST_INFO"/> </enum> -<enum name="ResourcePrefetchPredictorResourceStatus" type="int"> +<enum name="ResourcePrefetchPredictorResourceStatus"> <int value="0" label="RESOURCE_STATUS_HANDLED"/> <int value="1" label="RESOURCE_STATUS_NOT_HTTP_PAGE"/> <int value="2" label="RESOURCE_STATUS_NOT_HTTP_RESOURCE"/> @@ -31494,14 +31498,14 @@ <int value="64" label="RESOURCE_STATUS_HEADERS_MISSING"/> </enum> -<enum name="ResourceReporterCpuUsage" type="int"> +<enum name="ResourceReporterCpuUsage"> <int value="0" label="0-10%"/> <int value="1" label="10%-30%"/> <int value="2" label="30%-60%"/> <int value="4" label=">60%"/> </enum> -<enum name="ResourceReporterMemoryUsage" type="int"> +<enum name="ResourceReporterMemoryUsage"> <int value="0" label="0-200MB"/> <int value="1" label="200MB-400MB"/> <int value="2" label="400MB-600MB"/> @@ -31510,7 +31514,7 @@ <int value="16" label=">1GB."/> </enum> -<enum name="ResourceType" type="int"> +<enum name="ResourceType"> <int value="0" label="Main resource"/> <int value="1" label="Image"/> <int value="2" label="CSSS"/> @@ -31527,24 +31531,24 @@ <int value="13" label="Manifest"/> </enum> -<enum name="RestoredCachedStyleSheet" type="int"> +<enum name="RestoredCachedStyleSheet"> <int value="0" label="No usable cache found"/> <int value="1" label="Cached StyleSheetContents was reused"/> </enum> -<enum name="ReusePendingOrCommittedSiteEnum" type="int"> +<enum name="ReusePendingOrCommittedSiteEnum"> <int value="0" label="Had to create a new RenderProcessHost"/> <int value="1" label="Could reuse an existing RenderProcessHost"/> </enum> -<enum name="RevalidationPolicy" type="int"> +<enum name="RevalidationPolicy"> <int value="0" label="Use"/> <int value="1" label="Revalidate"/> <int value="2" label="Reload"/> <int value="3" label="Load"/> </enum> -<enum name="RunningMode" type="int"> +<enum name="RunningMode"> <obsolete> Removed 9/2016. </obsolete> @@ -31552,18 +31556,18 @@ <int value="1" label="Tabbed Mode"/> </enum> -<enum name="SadTabEvent" type="int"> +<enum name="SadTabEvent"> <int value="0" label="Displayed"/> <int value="1" label="Button clicked"/> <int value="2" label="Learn more clicked"/> </enum> -<enum name="SadTabKind" type="int"> +<enum name="SadTabKind"> <int value="0" label="Crash (Aw, Snap!)"/> <int value="1" label="Kill (He's dead, Jim!)"/> </enum> -<enum name="SafeBrowsingAttributionResultTypes" type="int"> +<enum name="SafeBrowsingAttributionResultTypes"> <int value="1" label="SUCCESS"/> <int value="2" label="SUCCESS_LANDING_PAGE"/> <int value="3" label="SUCCESS_LANDING_REFERRER"/> @@ -31571,7 +31575,7 @@ <int value="5" label="NAVIGATION_EVENT_NOT_FOUND"/> </enum> -<enum name="SafeBrowsingParseV4HashResult" type="int"> +<enum name="SafeBrowsingParseV4HashResult"> <int value="0" label="PARSE_FROM_STRING_ERROR"/> <int value="1" label="UNEXPECTED_THREAT_ENTRY_TYPE_ERROR"/> <int value="2" label="UNEXPECTED_THREAT_TYPE_ERROR"/> @@ -31582,7 +31586,7 @@ <int value="7" label="NO_THREAT_ERROR"/> </enum> -<enum name="SafeBrowsingParseV4UpdateResult" type="int"> +<enum name="SafeBrowsingParseV4UpdateResult"> <int value="0" label="PARSE_FROM_STRING_ERROR"/> <int value="1" label="NO_PLATFORM_TYPE_ERROR"/> <int value="2" label="NO_THREAT_ENTRY_TYPE_ERROR"/> @@ -31590,13 +31594,13 @@ <int value="4" label="NO_STATE_ERROR"/> </enum> -<enum name="SafeBrowsingResponse" type="int"> +<enum name="SafeBrowsingResponse"> <int value="0" label="NOT_BLACKLISTED"/> <int value="1" label="TIMEOUT"/> <int value="2" label="BLACKLISTED"/> </enum> -<enum name="SafeBrowsingV4ApplyUpdateResult" type="int"> +<enum name="SafeBrowsingV4ApplyUpdateResult"> <int value="0" label="APPLY_UPDATE_SUCCESS"/> <int value="1" label="UNEXPECTED_APPLY_UPDATE_FAILURE"/> <int value="2" label="PREFIX_SIZE_TOO_SMALL_FAILURE"/> @@ -31611,7 +31615,7 @@ <int value="11" label="CHECKSUM_MISMATCH_FAILURE"/> </enum> -<enum name="SafeBrowsingV4DecodeResult" type="int"> +<enum name="SafeBrowsingV4DecodeResult"> <int value="0" label="DECODE_SUCCESS"/> <int value="1" label="DECODE_NO_MORE_ENTRIES_FAILURE"/> <int value="2" label="DECODE_REQUESTED_TOO_MANY_BITS_FAILURE"/> @@ -31622,19 +31626,19 @@ <int value="7" label="DECODED_INTEGER_OVERFLOW_FAILURE"/> </enum> -<enum name="SafeBrowsingV4FullHashCacheResult" type="int"> +<enum name="SafeBrowsingV4FullHashCacheResult"> <int value="0" label="FULL_HASH_CACHE_MISS"/> <int value="1" label="FULL_HASH_CACHE_HIT"/> <int value="2" label="FULL_HASH_NEGATIVE_CACHE_HIT"/> </enum> -<enum name="SafeBrowsingV4GetHashCheckResult" type="int"> +<enum name="SafeBrowsingV4GetHashCheckResult"> <int value="0" label="GET_HASH_CHECK_EMPTY"/> <int value="1" label="GET_HASH_CHECK_HIT"/> <int value="2" label="GET_HASH_CHECK_MISS"/> </enum> -<enum name="SafeBrowsingV4OperationResult" type="int"> +<enum name="SafeBrowsingV4OperationResult"> <int value="0" label="STATUS_200"/> <int value="1" label="PARSE_ERROR (subset of STATUS_200)"/> <int value="2" label="NETWORK_ERROR"/> @@ -31644,7 +31648,7 @@ <int value="6" label="ALREADY_PENDING_ERROR"/> </enum> -<enum name="SafeBrowsingV4StoreReadResult" type="int"> +<enum name="SafeBrowsingV4StoreReadResult"> <int value="0" label="READ_SUCCESS"/> <int value="1" label="UNEXPECTED_READ_FAILURE"/> <int value="2" label="FILE_UNREADABLE_FAILURE"/> @@ -31656,7 +31660,7 @@ <int value="8" label="HASH_PREFIX_MAP_GENERATION_FAILURE"/> </enum> -<enum name="SafeBrowsingV4StoreWriteResult" type="int"> +<enum name="SafeBrowsingV4StoreWriteResult"> <int value="0" label="WRITE_SUCCESS"/> <int value="1" label="UNEXPECTED_WRITE_FAILURE"/> <int value="2" label="INVALID_RESPONSE_TYPE_FAILURE"/> @@ -31664,13 +31668,13 @@ <int value="4" label="UNABLE_TO_RENAME_FAILURE"/> </enum> -<enum name="SavePasswordPromptResponseType" type="int"> +<enum name="SavePasswordPromptResponseType"> <int value="0" label="NO_RESPONSE"/> <int value="1" label="REMEMBER_PASSWORD"/> <int value="2" label="DONT_REMEMBER_PASSWORD"/> </enum> -<enum name="SB2BloomFailure" type="int"> +<enum name="SB2BloomFailure"> <obsolete> Bloom filter support deleted in October 2012. </obsolete> @@ -31684,7 +31688,7 @@ <int value="7" label="READ_DATA"/> </enum> -<enum name="SB2BloomFilterFalsePositives" type="int"> +<enum name="SB2BloomFilterFalsePositives"> <obsolete> Bloom filter support deleted in October 2012. </obsolete> @@ -31692,7 +31696,7 @@ <int value="1" label="FALSE_POSITIVE_MISSES"/> </enum> -<enum name="SB2DatabaseFailure" type="int"> +<enum name="SB2DatabaseFailure"> <int value="0" label="FAILURE_DATABASE_CORRUPT"/> <int value="1" label="FAILURE_DATABASE_CORRUPT_HANDLER"/> <int value="2" label="FAILURE_BROWSE_DATABASE_UPDATE_BEGIN"/> @@ -31734,7 +31738,7 @@ <int value="38" label="FAILURE_MODULE_WHITELIST_DELETE"/> </enum> -<enum name="SB2DownloadChecks" type="int"> +<enum name="SB2DownloadChecks"> <int value="0" label="URL_CHECKS_TOTAL"/> <int value="1" label="URL_CHECKS_CANCELED"/> <int value="2" label="URL_CHECKS_MALWARE"/> @@ -31742,13 +31746,13 @@ <int value="4" label="HASH_CHECKS_MALWARE"/> </enum> -<enum name="SB2FilterLoad" type="int"> +<enum name="SB2FilterLoad"> <int value="0" label="ALL"/> <int value="1" label="PREFIX_SET"/> <int value="2" label="BLOOM_FILTER"/> </enum> -<enum name="SB2FormatEvent" type="int"> +<enum name="SB2FormatEvent"> <summary> Track information for various error cases in the safe-browsing store. </summary> @@ -31784,7 +31788,7 @@ </int> </enum> -<enum name="SB2GetHashResult" type="int"> +<enum name="SB2GetHashResult"> <int value="0" label="STATUS_200"/> <int value="1" label="STATUS_204"/> <int value="2" label="FULL_HASH_EMPTY (sum of STATUS_204, *_ERROR)"/> @@ -31796,7 +31800,7 @@ <int value="8" label="BACKOFF_ERROR"/> </enum> -<enum name="SB2InterstitialAction" type="int"> +<enum name="SB2InterstitialAction"> <obsolete> Deprecated 9/2014. </obsolete> @@ -31817,7 +31821,7 @@ <int value="14" label="PHISHING_SHOW_ADVANCED"/> </enum> -<enum name="SB2InterstitialActionDetails" type="int"> +<enum name="SB2InterstitialActionDetails"> <obsolete> Deprecated 9/2014. </obsolete> @@ -31831,7 +31835,7 @@ <int value="7" label="PHISHING_PROCEED_CROSS_SITE"/> </enum> -<enum name="SB2PrefixSetEvent" type="int"> +<enum name="SB2PrefixSetEvent"> <obsolete> Deprecated 9/2012. No longer generated. </obsolete> @@ -31857,7 +31861,7 @@ <int value="19" label="BLOOM_MISS_PREFIX_HIT"/> </enum> -<enum name="SB2RemoteCallResult" type="int"> +<enum name="SB2RemoteCallResult"> <int value="0" label="INTERNAL_ERROR"/> <int value="1" label="TIMEOUT"/> <int value="2" label="SAFE"/> @@ -31868,7 +31872,7 @@ <int value="7" label="UNSUPPORTED"/> </enum> -<enum name="SB2RemoteCallThreatSubType" type="int"> +<enum name="SB2RemoteCallThreatSubType"> <int value="0" label="No subtype added"/> <int value="1" label="Potentially Harmful App Landing URL"/> <int value="2" label="Potentially Harmful App Distribution URL"/> @@ -31878,12 +31882,12 @@ <int value="6" label="Phishing URL"/> </enum> -<enum name="SB2SideEffectFreeWhitelistStatus" type="int"> +<enum name="SB2SideEffectFreeWhitelistStatus"> <int value="0" label="Enabled"/> <int value="1" label="Disabled"/> </enum> -<enum name="SB2UpdateResult" type="int"> +<enum name="SB2UpdateResult"> <int value="0" label="FAIL"/> <int value="1" label="SUCCESS"/> <int value="2" label="BACKUP_CONNECT_FAIL"/> @@ -31894,7 +31898,7 @@ <int value="7" label="BACKUP_NETWORK_SUCCESS"/> </enum> -<enum name="SBClientDetectionPreClassificationCheckFail" type="int"> +<enum name="SBClientDetectionPreClassificationCheckFail"> <int value="0" label="PROXY_FETCH"/> <int value="1" label="PRIVATE_IP"/> <int value="2" label="OFF_THE_RECORD"/> @@ -31909,7 +31913,7 @@ <int value="11" label="SCHEME_NOT_SUPPORTED"/> </enum> -<enum name="SBClientDownloadCheckDownloadStats" type="int"> +<enum name="SBClientDownloadCheckDownloadStats"> <int value="0" label="INVALID_URL"/> <int value="1" label="SB_DISABLED"/> <int value="2" label="WHITELISTED_URL"/> @@ -31940,7 +31944,7 @@ <int value="27" label="VERDICT_UNKNOWN"/> </enum> -<enum name="SBClientDownloadCheckResult" type="int"> +<enum name="SBClientDownloadCheckResult"> <int value="0" label="UNKNOWN"/> <int value="1" label="SAFE"/> <int value="2" label="DANGEROUS"/> @@ -31949,7 +31953,7 @@ <int value="5" label="POTENTIALLY_UNWANTED"/> </enum> -<enum name="SBClientDownloadExtensions" type="int"> +<enum name="SBClientDownloadExtensions"> <int value="-1" label="File extension not categorized"/> <int value="0" label="EXE"/> <int value="1" label="MSI"/> @@ -32239,12 +32243,12 @@ <int value="285" label="HTML"/> </enum> -<enum name="SBClientDownloadIsSignedBinary" type="int"> +<enum name="SBClientDownloadIsSignedBinary"> <int value="0" label="Unsigned"/> <int value="1" label="Signed"/> </enum> -<enum name="SBClientDownloadPPAPIDownloadRequestOutcome" type="int"> +<enum name="SBClientDownloadPPAPIDownloadRequestOutcome"> <int value="0" label="(unknown)"/> <int value="1" label="Request destroyed before completion"/> <int value="2" label="Unsupported file type"/> @@ -32256,13 +32260,13 @@ <int value="8" label="Succeeded"/> </enum> -<enum name="SBClientMalwareSentReports" type="int"> +<enum name="SBClientMalwareSentReports"> <int value="0" label="Sent"/> <int value="1" label="Hit limit"/> <int value="2" label="Failed serialization"/> </enum> -<enum name="SBClientPhishingCancelClassificationReason" type="int"> +<enum name="SBClientPhishingCancelClassificationReason"> <int value="0" label="NAVIGATE_AWAY"/> <int value="1" label="NAVIGATE_WITHIN_PAGE"/> <int value="2" label="PAGE_RECAPTURED"/> @@ -32270,7 +32274,7 @@ <int value="4" label="NEW_PHISHING_SCORER"/> </enum> -<enum name="SBClientPhishingClientModelStatus" type="int"> +<enum name="SBClientPhishingClientModelStatus"> <int value="0" label="MODEL_SUCCESS"/> <int value="1" label="MODEL_NOT_CHANGED"/> <int value="2" label="MODEL_FETCH_FAILED"/> @@ -32282,7 +32286,7 @@ <int value="8" label="BAD_HASH_IDS"/> </enum> -<enum name="SBClientPhishingScorerCreationStatus" type="int"> +<enum name="SBClientPhishingScorerCreationStatus"> <int value="0" label="SUCCESS"/> <int value="1" label="MODEL_OPEN_FAIL"/> <int value="2" label="MODEL_FILE_EMPTY"/> @@ -32291,13 +32295,13 @@ <int value="5" label="MODEL_MISSING_FIELDS"/> </enum> -<enum name="SBClientPhishingSkipClassificationReason" type="int"> +<enum name="SBClientPhishingSkipClassificationReason"> <int value="0" label="Not skipped"/> <int value="1" label="Skipped: HTTPS"/> <int value="2" label="Skipped: Not a GET request"/> </enum> -<enum name="SBDownloadFeedbackUploadResult" type="int"> +<enum name="SBDownloadFeedbackUploadResult"> <int value="0" label="SUCCESS"/> <int value="1" label="UPLOAD_SUCCESS"/> <int value="2" label="UPLOAD_CANCELLED"/> @@ -32308,7 +32312,7 @@ <int value="7" label="UPLOAD_COMPLETE_RESPONSE_ERROR"/> </enum> -<enum name="SBFileTypeUpdateResult" type="int"> +<enum name="SBFileTypeUpdateResult"> <int value="1" label="SUCCESS"/> <int value="2" label="FAILED_EMPTY"/> <int value="3" label="FAILED_PROTO_PARSE"/> @@ -32319,7 +32323,7 @@ <int value="8" label="SKIPPED_VERSION_CHECK_EQUAL"/> </enum> -<enum name="ScheduledNavigationType" type="int"> +<enum name="ScheduledNavigationType"> <int value="0" label="(no gesture) ScheduledReload"/> <int value="1" label="(no gesture) ScheduledFormSubmission"/> <int value="2" label="(no gesture) ScheduledURLNavigation"/> @@ -32334,12 +32338,12 @@ <int value="11" label="(gesture) ScheduledPageBlock"/> </enum> -<enum name="ScoutActiveExtendedReportingPref" type="int"> +<enum name="ScoutActiveExtendedReportingPref"> <int value="0" label="Active pref is the legacy SBER pref"/> <int value="1" label="Active pref is the new Scout pref"/> </enum> -<enum name="ScoutTransitionReason" type="int"> +<enum name="ScoutTransitionReason"> <int value="0" label="Flag forced Scout Group to true"/> <int value="1" label="Flag forced Scout Group to false"/> <int value="2" label="User in OnlyShowScout group, enters Scout Group"/> @@ -32357,30 +32361,30 @@ <int value="9" label="Rollback: SBER2 absent so SBER1 must be cleared"/> </enum> -<enum name="ScrollingThreadStatus" type="int"> +<enum name="ScrollingThreadStatus"> <int value="0" label="SCROLLING_ON_COMPOSITOR"/> <int value="1" label="SCROLLING_ON_COMPOSITOR_BLOCKED_ON_MAIN"/> <int value="2" label="SCROLLING_ON_MAIN"/> </enum> -<enum name="ScrollThread" type="int"> +<enum name="ScrollThread"> <int value="0" label="Scroll on impl-thread"/> <int value="1" label="Scroll on main-thread"/> </enum> -<enum name="SCTCanBeChecked" type="int"> +<enum name="SCTCanBeChecked"> <int value="0" label="No valid STH"/> <int value="1" label="Requires newer STH"/> <int value="2" label="Can be checked for inclusion"/> </enum> -<enum name="SCTOrigin" type="int"> +<enum name="SCTOrigin"> <int value="0" label="SCT_EMBEDDED"/> <int value="1" label="SCT_FROM_TLS_EXTENSION"/> <int value="2" label="SCT_FROM_OCSP_RESPONSE"/> </enum> -<enum name="SCTVerifyStatus" type="int"> +<enum name="SCTVerifyStatus"> <int value="0" label="SCT_STATUS_NONE"/> <int value="1" label="SCT_STATUS_LOG_UNKNOWN"/> <int value="2" label="DEPRECATED: SCT_STATUS_INVALID"/> @@ -32389,7 +32393,7 @@ <int value="5" label="SCT_STATUS_INVALID_TIMESTAMP"/> </enum> -<enum name="SdchDictionaryFate" type="int"> +<enum name="SdchDictionaryFate"> <summary> Fate of an Sdch dictionary, on load and eviction. See net/sdch/sdch_owner.cc. @@ -32406,7 +32410,7 @@ <int value="10" label="UNLOAD_FOR_DESTRUCTION"/> </enum> -<enum name="SdchPersistenceFailureReason" type="int"> +<enum name="SdchPersistenceFailureReason"> <summary> Errors that can occur when reading in or writing out persisted dictionary information. See enum in net/sdch/sdch_owner.h for more information. @@ -32417,7 +32421,7 @@ <int value="4" label="OTHER"/> </enum> -<enum name="SdchProblemCode" type="int"> +<enum name="SdchProblemCode"> <summary> SDCH problem codes, listed in net/base/sdch_problem_code_list.h </summary> @@ -32512,7 +32516,7 @@ <int value="107" label="DICTIONARY_USED_AFTER_DELETION"/> </enum> -<enum name="SdchResponseCorruptionDetectionCauses" type="int"> +<enum name="SdchResponseCorruptionDetectionCauses"> <summary> SDCH decode corruption detection cases, listed in net/filter/sdch_filter.cc. See also comments in SdchFilter::ReadFilteredData in the same file. @@ -32526,7 +32530,7 @@ <int value="7" label="RESPONSE_ENCODING_LIE"/> </enum> -<enum name="SearchAccessPoint" type="int"> +<enum name="SearchAccessPoint"> <int value="0" label="Omnibox"/> <int value="1" label="Omnibox Instant"/> <int value="2" label="Direct Navigation"/> @@ -32539,7 +32543,7 @@ <int value="9" label="Other Instant"/> </enum> -<enum name="SearchAnswerRequestResult" type="int"> +<enum name="SearchAnswerRequestResult"> <int value="0" label="Another Request Started"/> <int value="1" label="Failed"/> <int value="2" label="No Answer"/> @@ -32547,7 +32551,7 @@ <int value="4" label="Received Answer - Too Large"/> </enum> -<enum name="SearchEngine" type="int"> +<enum name="SearchEngine"> <obsolete> Deprecated 8/2013. No longer generated. </obsolete> @@ -32591,26 +32595,26 @@ <int value="33" label="NONE"/> </enum> -<enum name="SearchEntryPoint" type="int"> +<enum name="SearchEntryPoint"> <int value="0" label="From search widget"/> <int value="1" label="From omnibox"/> </enum> -<enum name="SearchWidgetUseInfo" type="int"> +<enum name="SearchWidgetUseInfo"> <int value="0" label="Present in partnership device"/> <int value="1" label="Not present in partnership device"/> <int value="2" label="Present in non-partnership device"/> <int value="3" label="Not present in non-partnership device"/> </enum> -<enum name="SecurityInterstitialDecision" type="int"> +<enum name="SecurityInterstitialDecision"> <int value="0" label="SHOW"/> <int value="1" label="PROCEED"/> <int value="2" label="DONT_PROCEED"/> <int value="3" label="PROCEEDING_DISABLED"/> </enum> -<enum name="SecurityInterstitialInteraction" type="int"> +<enum name="SecurityInterstitialInteraction"> <int value="0" label="TOTAL_VISITS"/> <int value="1" label="SHOW_ADVANCED"/> <int value="2" label="SHOW_PRIVACY"/> @@ -32625,14 +32629,14 @@ <int value="11" label="SHOW_WHITEPAPER"/> </enum> -<enum name="SelectFileDialogScope" type="int"> +<enum name="SelectFileDialogScope"> <int value="0" label="Generic files"/> <int value="1" label="Images"/> <int value="2" label="Videos"/> <int value="3" label="Images and videos"/> </enum> -<enum name="ServiceProcessEventType" type="int"> +<enum name="ServiceProcessEventType"> <int value="0" label="SERVICE_EVENT_INITIALIZE"/> <int value="1" label="SERVICE_EVENT_ENABLED_ON_LAUNCH"/> <int value="2" label="SERVICE_EVENT_ENABLE"/> @@ -32651,14 +32655,14 @@ <int value="15" label="SERVICE_PRINTERS_REPLY"/> </enum> -<enum name="ServicesCustomizationLoadResult" type="int"> +<enum name="ServicesCustomizationLoadResult"> <int value="0" label="Manifest loaded successfully"/> <int value="1" label="Manifest not found on server"/> <int value="2" label="Manifest parsing error"/> <int value="3" label="Failed to load manifest after N retries"/> </enum> -<enum name="ServiceUtilityProcessHostEventType" type="int"> +<enum name="ServiceUtilityProcessHostEventType"> <int value="0" label="SERVICE_UTILITY_STARTED"/> <int value="1" label="SERVICE_UTILITY_DISCONNECTED"/> <int value="2" label="SERVICE_UTILITY_METAFILE_REQUEST"/> @@ -32673,7 +32677,7 @@ <int value="11" label="SERVICE_UTILITY_FAILED_TO_START"/> </enum> -<enum name="ServiceWorkerCacheErrorType" type="int"> +<enum name="ServiceWorkerCacheErrorType"> <int value="0" label="OK"/> <int value="1" label="Exists Error"/> <int value="2" label="Storage Error"/> @@ -32681,7 +32685,7 @@ <int value="4" label="Quota Exceeded Error"/> </enum> -<enum name="ServiceWorkerCacheResponseType" type="int"> +<enum name="ServiceWorkerCacheResponseType"> <int value="0" label="Basic"/> <int value="1" label="CORS"/> <int value="2" label="Default"/> @@ -32690,7 +32694,7 @@ <int value="5" label="OpaqueRedirect"/> </enum> -<enum name="ServiceWorkerContextRequestHandlerStatus" type="int"> +<enum name="ServiceWorkerContextRequestHandlerStatus"> <summary> The result of ServiceWorkerContextHandler handling a request for a service worker script. From ServiceWorkerContextHandler::CreateJobStatus. @@ -32709,7 +32713,7 @@ <int value="10" label="Error: out of resource ids"/> </enum> -<enum name="ServiceWorkerDatabaseStatus" type="int"> +<enum name="ServiceWorkerDatabaseStatus"> <int value="0" label="OK"/> <int value="1" label="Not Found Error"/> <int value="2" label="IO Error"/> @@ -32718,13 +32722,13 @@ <int value="5" label="Not Supported Error"/> </enum> -<enum name="ServiceWorkerDeleteAndStartOverResult" type="int"> +<enum name="ServiceWorkerDeleteAndStartOverResult"> <int value="0" label="OK"/> <int value="1" label="Failed to delete ServiceWorkerDatabase"/> <int value="2" label="Failed to delete ServiceWorkerDiskCache"/> </enum> -<enum name="ServiceWorkerDiskCacheMigrationResult" type="int"> +<enum name="ServiceWorkerDiskCacheMigrationResult"> <obsolete> Deprecated because the migrator was removed as of 12/2015. </obsolete> @@ -32734,7 +32738,7 @@ <int value="3" label="MIGRATION_ERROR_UPDATE_DATABASE"/> </enum> -<enum name="ServiceWorkerDiskCacheMigrationStatus" type="int"> +<enum name="ServiceWorkerDiskCacheMigrationStatus"> <obsolete> Deprecated because the migrator was removed as of 12/2015. </obsolete> @@ -32752,13 +32756,13 @@ <int value="11" label="MIGRATION_ERROR_WRITE_RESPONSE_DATA"/> </enum> -<enum name="ServiceWorkerEventHandleRatioType" type="int"> +<enum name="ServiceWorkerEventHandleRatioType"> <int value="0" label="None"/> <int value="1" label="Some"/> <int value="2" label="All"/> </enum> -<enum name="ServiceWorkerMetrics.EventType" type="int"> +<enum name="ServiceWorkerMetrics.EventType"> <int value="0" label="ACTIVATE"/> <int value="1" label="INSTALL"/> <int value="2" label="FETCH (unused)"/> @@ -32788,7 +32792,7 @@ <int value="26" label="BACKGROUND_FETCHED"/> </enum> -<enum name="ServiceWorkerPreparationType" type="int"> +<enum name="ServiceWorkerPreparationType"> <summary> The type of preparation that was required for the browser to find and possibly start up a service worker to dispatch a fetch event to. From @@ -32806,13 +32810,13 @@ <int value="6" label="The worker started up during browser startup."/> </enum> -<enum name="ServiceWorkerReadResponseResult" type="int"> +<enum name="ServiceWorkerReadResponseResult"> <int value="0" label="OK"/> <int value="1" label="Read headers error"/> <int value="2" label="Read data error"/> </enum> -<enum name="ServiceWorkerResponseError" type="int"> +<enum name="ServiceWorkerResponseError"> <int value="0" label="ErrorUnknown"/> <int value="1" label="ErrorPromiseRejected"/> <int value="2" label="ErrorDefaultPrevented"/> @@ -32830,7 +32834,7 @@ <int value="14" label="RedirectedResponseForNotFollowRequest"/> </enum> -<enum name="ServiceWorkerSite" type="int"> +<enum name="ServiceWorkerSite"> <int value="0" label="Other (unused)"/> <int value="1" label="NewTabPage"/> <int value="2" label="WithFetchHandler"/> @@ -32840,7 +32844,7 @@ <int value="6" label="Google Docs and Drive"/> </enum> -<enum name="ServiceWorkerStatusCode" type="int"> +<enum name="ServiceWorkerStatusCode"> <int value="0" label="SERVICE_WORKER_OK"/> <int value="1" label="SERVICE_WORKER_ERROR_FAILED"/> <int value="2" label="SERVICE_WORKER_ERROR_ABORT"/> @@ -32863,13 +32867,13 @@ <int value="19" label="SERVICE_WORKER_ERROR_DISABLED_WORKER (unused)"/> </enum> -<enum name="ServiceWorkerStoppedStatus" type="int"> +<enum name="ServiceWorkerStoppedStatus"> <int value="0" label="NORMAL"/> <int value="1" label="DETACH_BY_REGISTRY"/> <int value="2" label="TIMEOUT"/> </enum> -<enum name="ServiceWorkerStopStatus" type="int"> +<enum name="ServiceWorkerStopStatus"> <obsolete> Deprecated Oct 2015. No longer generated in the code. </obsolete> @@ -32879,7 +32883,7 @@ <int value="3" label="STOP_STATUS_STALLED_THEN_STOPPED"/> </enum> -<enum name="ServiceWorkerURLRequestJobResult" type="int"> +<enum name="ServiceWorkerURLRequestJobResult"> <int value="0" label="REQUEST_JOB_FALLBACK_RESPONSE"/> <int value="1" label="REQUEST_JOB_FALLBACK_FOR_CORS"/> <int value="2" label="REQUEST_JOB_HEADERS_ONLY_RESPONSE"/> @@ -32903,13 +32907,13 @@ <int value="20" label="REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED"/> </enum> -<enum name="ServiceWorkerWriteResponseResult" type="int"> +<enum name="ServiceWorkerWriteResponseResult"> <int value="0" label="OK"/> <int value="1" label="Write headers error"/> <int value="2" label="Write data error"/> </enum> -<enum name="SessionCrashedBubbleUserAction" type="int"> +<enum name="SessionCrashedBubbleUserAction"> <int value="0" label="The bubble was shown"/> <int value="1" label="There was an error when showing the bubble."/> <int value="2" label="The Restore button was clicked"/> @@ -32921,12 +32925,12 @@ <int value="8" label="The Startup pages button was clicked."/> </enum> -<enum name="SessionRestoreActions" type="int"> +<enum name="SessionRestoreActions"> <int value="0" label="A session restore was started"/> <int value="1" label="A session restore deferred one or more tabs"/> </enum> -<enum name="SessionRestoreTabActions" type="int"> +<enum name="SessionRestoreTabActions"> <int value="0" label="A tab was created"/> <int value="1" label="A tab's content was automatically loaded"/> <int value="2" label="The loading of a tab's content was deferred"/> @@ -32934,14 +32938,14 @@ <int value="4" label="A tab's content automatically started to load"/> </enum> -<enum name="SessionStartupPref" type="int"> +<enum name="SessionStartupPref"> <int value="0" label="Open home page (unused)"/> <int value="1" label="Continue from last opened pages"/> <int value="4" label="Open URLs"/> <int value="5" label="Open new tab page"/> </enum> -<enum name="SessionStartupType" type="int"> +<enum name="SessionStartupType"> <obsolete> Deprecated 8/2013. No longer generated. </obsolete> @@ -32951,7 +32955,7 @@ <int value="3" label="Specified URLs"/> </enum> -<enum name="SessionStorageDatabaseOpen" type="int"> +<enum name="SessionStorageDatabaseOpen"> <int value="0" label="OK">Succesfully opened the database.</int> <int value="1" label="Recovered"> Failed to open the existing db, deleted it, and created a new empty db. @@ -32980,7 +32984,7 @@ </int> </enum> -<enum name="SetDefaultAttemptResult" type="int"> +<enum name="SetDefaultAttemptResult"> <obsolete> Deprecated 2016/03. Replaced by DefaultWebClientState. </obsolete> @@ -33011,7 +33015,7 @@ </int> </enum> -<enum name="SettingsInteractionConcludeReason" type="int"> +<enum name="SettingsInteractionConcludeReason"> <int value="0" label="Registry watcher"> A change to the protocol registry key was detected. </int> @@ -33020,7 +33024,7 @@ </int> </enum> -<enum name="SettingsResetPromptConfigError" type="int"> +<enum name="SettingsResetPromptConfigError"> <int value="1" label="Config Ok"/> <int value="2" label="Missing domain_hashes param"/> <int value="3" label="Bad domain_hashes param"/> @@ -33032,7 +33036,7 @@ <int value="9" label="Bad time_between_prompts_seconds param"/> </enum> -<enum name="SettingsResetPromptResetState" type="int"> +<enum name="SettingsResetPromptResetState"> <int value="1" label="Reset required"/> <int value="2" label="Domain not matched, no reset required"/> <int value="3" label="Already prompted for setting, no reset required"/> @@ -33041,13 +33045,13 @@ <int value="6" label="Policy detected, no reset required"/> </enum> -<enum name="SettingsResetPromptSettingsReset" type="int"> +<enum name="SettingsResetPromptSettingsReset"> <int value="1" label="Homepage"/> <int value="2" label="Default search engine"/> <int value="3" label="Startup URLs"/> </enum> -<enum name="SettingsSections" type="int"> +<enum name="SettingsSections"> <summary> A collection of sections from chrome://settings. Used for metrics about searching within the settings options. @@ -33095,7 +33099,7 @@ <int value="40" label="Prefs Dump"/> </enum> -<enum name="SetupInstallResult" type="int"> +<enum name="SetupInstallResult"> <int value="0" label="First install of Chrome succeeded."/> <int value="1" label="Same version reinstalled for repair."/> <int value="2" label="Chrome successfully updated to new version."/> @@ -33152,7 +33156,7 @@ label="Unpacking the (possibly patched) uncompressed archive failed."/> </enum> -<enum name="SetupSingletonAcquisitionResult" type="int"> +<enum name="SetupSingletonAcquisitionResult"> <int value="0" label="The setup singleton was acquired successfully."/> <int value="1" label="Acquisition of the exit event mutex timed out."/> <int value="2" label="Acquisition of the setup mutex timed out."/> @@ -33161,7 +33165,7 @@ <int value="5" label="Creation of the exit event mutex failed."/> </enum> -<enum name="SHA1Status" type="int"> +<enum name="SHA1Status"> <summary> Whether or not SHA-1 was present in a certificate chain and, if it was, when the leaf certificate expired. @@ -33173,7 +33177,7 @@ <int value="4" label="Expires before Jan 1, 2016"/> </enum> -<enum name="ShaderModel" type="int"> +<enum name="ShaderModel"> <summary>The GPU's Direct3D shader model version.</summary> <int value="0" label="SHADER_MODEL_UNKNOWN"/> <int value="1" label="SHADER_MODEL_2_0"/> @@ -33183,7 +33187,7 @@ <int value="5" label="SHADER_MODEL_5_0"/> </enum> -<enum name="SharedMemoryCreateError" type="int"> +<enum name="SharedMemoryCreateError"> <int value="0" label="SUCCESS"> The shared memory region was successfully created. </int> @@ -33211,7 +33215,7 @@ </int> </enum> -<enum name="ShelfAlignmentValue" type="int"> +<enum name="ShelfAlignmentValue"> <summary> The alignment of the shelf area (see ash/launcher/launcher_view.cc). </summary> @@ -33220,7 +33224,7 @@ <int value="2" label="Right"/> </enum> -<enum name="ShillSuspendTerminationDarkResumeActionResult" type="int"> +<enum name="ShillSuspendTerminationDarkResumeActionResult"> <summary> The termination/suspend/dark resume action result types come from SuspendActionResult in shill/metrics.h @@ -33229,7 +33233,7 @@ <int value="1" label="Failure"/> </enum> -<enum name="ShouldAllowOpenURLFailureReason" type="int"> +<enum name="ShouldAllowOpenURLFailureReason"> <summary> Specifies the reason why the web-accessible resource check in ShouldAllowOpenURL fails. @@ -33242,7 +33246,7 @@ <int value="3" label="Resource is not web-accessible (most common)"/> </enum> -<enum name="ShouldAllowOpenURLFailureScheme" type="int"> +<enum name="ShouldAllowOpenURLFailureScheme"> <!-- Generated from chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc --> <int value="0" label="SCHEME_UNKNOWN"/> @@ -33267,7 +33271,7 @@ <int value="19" label="SCHEME_FILESYSTEM"/> </enum> -<enum name="ShutdownReason" type="int"> +<enum name="ShutdownReason"> <summary> The reason that the Chrome OS power manager shut down or rebooted the system. @@ -33281,27 +33285,27 @@ <int value="6" label="Dark resume failed"/> </enum> -<enum name="ShutdownType" type="int"> +<enum name="ShutdownType"> <int value="0" label="Not valid">Invalid value.</int> <int value="1" label="Window close">The last browser window was closed.</int> <int value="2" label="Browser exit">User clicked on the Exit menu item.</int> <int value="3" label="End session">OS is logging off or shutting down.</int> </enum> -<enum name="SideloadUIEvents" type="int"> +<enum name="SideloadUIEvents"> <int value="0" label="Extension installed"/> <int value="1" label="Extension ignored"/> <int value="2" label="Extension re-enabled"/> <int value="3" label="Extension uninstalled"/> </enum> -<enum name="SideloadWipeoutBubble" type="int"> +<enum name="SideloadWipeoutBubble"> <int value="0" label="Learn more"/> <int value="1" label="Settings page"/> <int value="2" label="Dismiss"/> </enum> -<enum name="SigninAccessPoint" type="int"> +<enum name="SigninAccessPoint"> <int value="0" label="Start page"/> <int value="1" label="NTP Link"/> <int value="2" label="Menu"/> @@ -33328,7 +33332,7 @@ <int value="23" label="Force signin warning"/> </enum> -<enum name="SigninAccountEquality" type="int"> +<enum name="SigninAccountEquality"> <int value="0" label="Both Equal"/> <int value="1" label="Both Different"/> <int value="2" label="Only Same Email"/> @@ -33336,7 +33340,7 @@ <int value="4" label="Email Fallback"/> </enum> -<enum name="SigninAccountReconcilorState" type="int"> +<enum name="SigninAccountReconcilorState"> <int value="0" label="OK"> The account reconcilor has finished running and is up-to-date. </int> @@ -33348,13 +33352,13 @@ </int> </enum> -<enum name="SigninChoice" type="int"> +<enum name="SigninChoice"> <int value="0" label="Cancel"/> <int value="1" label="Continue"/> <int value="2" label="New Profile"/> </enum> -<enum name="SigninFlowConfirmations" type="int"> +<enum name="SigninFlowConfirmations"> <int value="0" label="Shown"/> <int value="1" label="OK"/> <int value="2" label="Return"/> @@ -33371,7 +33375,7 @@ <int value="13" label="Learn more undo"/> </enum> -<enum name="SigninHelperFlow" type="int"> +<enum name="SigninHelperFlow"> <int value="0" label="Shown">The signin flow was shown to the user.</int> <int value="1" label="Accepted">The user pressed accept to sign in.</int> <int value="2" label="Rejected">The user pressed the reject to sign in.</int> @@ -33400,14 +33404,14 @@ <int value="10" label="Undo">The sync was aborted with an undo button.</int> </enum> -<enum name="SigninInvestigatedScenario" type="int"> +<enum name="SigninInvestigatedScenario"> <int value="0" label="Upgrade low risk"/> <int value="1" label="Upgrade high risk"/> <int value="2" label="Same account"/> <int value="3" label="Different account"/> </enum> -<enum name="SigninReason" type="int"> +<enum name="SigninReason"> <int value="0" label="Signin primary account"/> <int value="1" label="Add secondary account"/> <int value="2" label="Reauthentication"/> @@ -33415,12 +33419,12 @@ <int value="4" label="Typed URL with unknown reason"/> </enum> -<enum name="SigninReauthStates" type="int"> +<enum name="SigninReauthStates"> <int value="0" label="Account mismatch"/> <int value="1" label="Reauth Shown"/> </enum> -<enum name="SigninSignoutProfile" type="int"> +<enum name="SigninSignoutProfile"> <int value="0" label="Preference changed"> The preference or policy controlling if signin is valid has changed. </int> @@ -33448,7 +33452,7 @@ </int> </enum> -<enum name="SigninSource" type="int"> +<enum name="SigninSource"> <int value="0" label="Start page"/> <int value="1" label="NTP Link"/> <int value="2" label="Menu"/> @@ -33464,13 +33468,13 @@ <int value="12" label="Unknown"/> </enum> -<enum name="SigninTokenTableReadTokenFromDBResult" type="int"> +<enum name="SigninTokenTableReadTokenFromDBResult"> <int value="0" label="Success"/> <int value="1" label="Decrypt failed"/> <int value="2" label="Read DB failed (bad entry)"/> </enum> -<enum name="SigninXDevicePromoEligibility" type="int"> +<enum name="SigninXDevicePromoEligibility"> <int value="0" label="Eligible">The user is eligible for the promo.</int> <int value="1" label="Opted Out"> The profile has previously opted out of the promo. @@ -33494,7 +33498,7 @@ </int> </enum> -<enum name="SigninXDevicePromoInitialized" type="int"> +<enum name="SigninXDevicePromoInitialized"> <int value="0" label="Initialized"> The promo was initialized successfully. </int> @@ -33506,23 +33510,23 @@ </int> </enum> -<enum name="SimpleCache.EntryCreatedAndStream2Omitted" type="int"> +<enum name="SimpleCache.EntryCreatedAndStream2Omitted"> <int value="0" label="Stream 2 file was present"/> <int value="1" label="Empty stream 2 file was omitted"/> </enum> -<enum name="SimpleCache.EntryOpenedAndStream2Removed" type="int"> +<enum name="SimpleCache.EntryOpenedAndStream2Removed"> <int value="0" label="Stream 2 file was already omitted or not empty"/> <int value="1" label="Empty stream 2 file removed"/> </enum> -<enum name="SimpleCache.FileDescriptorLimitStatus" type="int"> +<enum name="SimpleCache.FileDescriptorLimitStatus"> <int value="0" label="Unsupported"/> <int value="1" label="Supported but failed"/> <int value="2" label="Succeeded"/> </enum> -<enum name="SimpleCacheHeaderSizeChange" type="int"> +<enum name="SimpleCacheHeaderSizeChange"> <int value="0" label="Written for the first time"/> <int value="1" label="Rewritten with same size"/> <int value="2" label="Rewritten with larger size"/> @@ -33530,26 +33534,26 @@ <int value="4" label="Unexpected header stream write"/> </enum> -<enum name="SimpleCacheIndexInitializeMethod" type="int"> +<enum name="SimpleCacheIndexInitializeMethod"> <int value="0" label="Directory Scan"/> <int value="1" label="Index File"/> <int value="2" label="New Cache"/> </enum> -<enum name="SimpleCacheIndexWriteReason" type="int"> +<enum name="SimpleCacheIndexWriteReason"> <int value="0" label="Shutdown"/> <int value="1" label="Startup Merge"/> <int value="2" label="Saved While Idle"/> <int value="3" label="Stopped (Android only)"/> </enum> -<enum name="SimpleCacheOpenEntryIndexState" type="int"> +<enum name="SimpleCacheOpenEntryIndexState"> <int value="0" label="No index"/> <int value="1" label="Hit"/> <int value="2" label="Miss"/> </enum> -<enum name="SimpleCacheReadParallelizable" type="int"> +<enum name="SimpleCacheReadParallelizable"> <int value="0" label="Standalone Read (obsolete)"/> <int value="1" label="Follows read"/> <int value="2" label="Follows conflicting write"/> @@ -33558,7 +33562,7 @@ <int value="5" label="Read alone in queue"/> </enum> -<enum name="SimpleCacheReadResult" type="int"> +<enum name="SimpleCacheReadResult"> <int value="0" label="Success"/> <int value="1" label="Invalid Argument"/> <int value="2" label="Nonblocking Empty Return"/> @@ -33568,33 +33572,33 @@ <int value="6" label="Synchronous Checksum Failure"/> </enum> -<enum name="SimpleCacheStaleIndexQuality" type="int"> +<enum name="SimpleCacheStaleIndexQuality"> <int value="0" label="OK"/> <int value="1" label="Missed Entries"/> <int value="2" label="Extra Entries"/> <int value="3" label="Both"/> </enum> -<enum name="SimpleCacheSyncCheckEOFResult" type="int"> +<enum name="SimpleCacheSyncCheckEOFResult"> <int value="0" label="Success"/> <int value="1" label="Read Failure"/> <int value="2" label="Magic Number Mismatch"/> <int value="3" label="CRC Mismatch"/> </enum> -<enum name="SimpleCacheSyncCloseResult" type="int"> +<enum name="SimpleCacheSyncCloseResult"> <int value="0" label="Success"/> <int value="1" label="Write Failure"/> </enum> -<enum name="SimpleCacheSyncCreateResult" type="int"> +<enum name="SimpleCacheSyncCreateResult"> <int value="0" label="Success"/> <int value="1" label="Platform File Error"/> <int value="2" label="Can't Write Header"/> <int value="3" label="Can't Write Key"/> </enum> -<enum name="SimpleCacheSyncOpenResult" type="int"> +<enum name="SimpleCacheSyncOpenResult"> <int value="0" label="Success"/> <int value="1" label="Platform File Error"/> <int value="2" label="Can't Read Header"/> @@ -33607,13 +33611,13 @@ <int value="9" label="Invalid File Length"/> </enum> -<enum name="SimpleCacheSyncSHA256Result" type="int"> +<enum name="SimpleCacheSyncSHA256Result"> <int value="0" label="Not Present"/> <int value="1" label="Matched"/> <int value="2" label="Did Not Match"/> </enum> -<enum name="SimpleCacheSyncWriteResult" type="int"> +<enum name="SimpleCacheSyncWriteResult"> <int value="0" label="Success"/> <int value="1" label="Pretruncate Failure"/> <int value="2" label="Write Failure"/> @@ -33623,7 +33627,7 @@ <int value="6" label="Lazy Initialization Failure"/> </enum> -<enum name="SimpleCacheWriteDependencyType" type="int"> +<enum name="SimpleCacheWriteDependencyType"> <int value="0" label="First operation in the queue (Optimistic)"/> <int value="1" label="Follows conflicting optimistic write"/> <int value="2" label="Follows non conflicting optimistic write"/> @@ -33634,7 +33638,7 @@ <int value="7" label="Follows other operation"/> </enum> -<enum name="SimpleCacheWriteResult" type="int"> +<enum name="SimpleCacheWriteResult"> <int value="0" label="Success"/> <int value="1" label="Invalid Argument"/> <int value="2" label="Over Max Size"/> @@ -33643,7 +33647,7 @@ <int value="5" label="Fast Empty Return (Success)"/> </enum> -<enum name="SimpleGeolocationRequestEvent" type="int"> +<enum name="SimpleGeolocationRequestEvent"> <int value="0" label="Request start"/> <int value="1" label="Response success"/> <int value="2" label="Response not OK"/> @@ -33651,31 +33655,31 @@ <int value="4" label="Response malformed"/> </enum> -<enum name="SimpleGeolocationRequestHasCellTowers" type="int"> +<enum name="SimpleGeolocationRequestHasCellTowers"> <int value="0" label="No cell tower data in request."/> <int value="1" label="Cell tower data present."/> </enum> -<enum name="SimpleGeolocationRequestHasWiFiAccessPoints" type="int"> +<enum name="SimpleGeolocationRequestHasWiFiAccessPoints"> <int value="0" label="No WiFi data in request."/> <int value="1" label="WiFi data present."/> </enum> -<enum name="SimpleGeolocationRequestResult" type="int"> +<enum name="SimpleGeolocationRequestResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Server error"/> <int value="3" label="Request is cancelled."/> </enum> -<enum name="SimpleIndexState" type="int"> +<enum name="SimpleIndexState"> <int value="0" label="Corrupt"/> <int value="1" label="Stale"/> <int value="2" label="Fresh"/> <int value="3" label="Fresh index with cache updated since backend start"/> </enum> -<enum name="SiteEngagementServiceEngagementType" type="int"> +<enum name="SiteEngagementServiceEngagementType"> <int value="0" label="Navigation"/> <int value="1" label="Keypress"/> <int value="2" label="Mouse down"/> @@ -33688,7 +33692,7 @@ <int value="9" label="Notification interaction"/> </enum> -<enum name="SiteIsolationMimeType" type="int"> +<enum name="SiteIsolationMimeType"> <int value="0" label="HTML"/> <int value="1" label="XML"/> <int value="2" label="JSON"/> @@ -33696,14 +33700,14 @@ <int value="4" label="Others"/> </enum> -<enum name="SkiaFilterQuality" type="int"> +<enum name="SkiaFilterQuality"> <int value="0" label="None"/> <int value="1" label="Low"/> <int value="2" label="Medium"/> <int value="3" label="High"/> </enum> -<enum name="SkiaLockTexturePath" type="int"> +<enum name="SkiaLockTexturePath"> <int value="0" label="Failure"/> <int value="1" label="Pre-Existing"/> <int value="2" label="Native"/> @@ -33712,14 +33716,14 @@ <int value="5" label="RGBA"/> </enum> -<enum name="SkiaScaleFactor" type="int"> +<enum name="SkiaScaleFactor"> <int value="0" label="Upscale"/> <int value="1" label="No Scale"/> <int value="2" label="Downscale"/> <int value="3" label="Large Downscale"/> </enum> -<enum name="SnackbarIdentifier" type="int"> +<enum name="SnackbarIdentifier"> <int value="-2" label="TEST_SNACKBAR"/> <int value="-1" label="UNKNOWN"/> <int value="0" label="BOOKMARK_ADDED"/> @@ -33745,7 +33749,7 @@ <int value="20" label="TRANSLATE_NEVER_SITE"/> </enum> -<enum name="SnippetOpenMethod" type="int"> +<enum name="SnippetOpenMethod"> <int value="0" label="Plain click"/> <int value="1" label="New Window"/> <int value="2" label="New Tab"/> @@ -33753,7 +33757,7 @@ <int value="4" label="Save for Offline"/> </enum> -<enum name="SnippetsInteractions" type="int"> +<enum name="SnippetsInteractions"> <int value="0" label="Snippets were shown to the user"/> <int value="1" label="User scrolled through the snippets"/> <int value="2" label="User clicked on a snippet into the host website"/> @@ -33764,7 +33768,7 @@ label="User scrolled below the fold (max once per NTP load). Obsolete."/> </enum> -<enum name="SocketErrorCode" type="int"> +<enum name="SocketErrorCode"> <int value="0" label="ERR_MSG_TOO_BIG"/> <int value="1" label="ERR_ADDRESS_UNREACHABLE"/> <int value="2" label="ERR_ADDRESS_INVALID"/> @@ -33775,7 +33779,7 @@ <int value="7" label="ERR_OTHER"/> </enum> -<enum name="SocketStreamConnectionType" type="int"> +<enum name="SocketStreamConnectionType"> <int value="0" label="None"/> <int value="1" label="All"/> <int value="2" label="Tunnel"/> @@ -33784,13 +33788,13 @@ <int value="5" label="Secure proxy"/> </enum> -<enum name="SocketStreamProtocolType" type="int"> +<enum name="SocketStreamProtocolType"> <int value="0" label="unknown"/> <int value="1" label="ws"/> <int value="2" label="wss"/> </enum> -<enum name="SoftwareImageDecodeState" type="int"> +<enum name="SoftwareImageDecodeState"> <int value="0" label="Wasted"/> <int value="1" label="Used"/> <int value="2" label="Used, relock failed"/> @@ -33798,18 +33802,18 @@ <int value="4" label="Used, relocked"/> </enum> -<enum name="SoftwareReporterExperimentError" type="int"> +<enum name="SoftwareReporterExperimentError"> <int value="1" label="Bad tag"/> <int value="2" label="Bad parameters"/> </enum> -<enum name="SoftwareReporterLogsUploadEnabled" type="int"> +<enum name="SoftwareReporterLogsUploadEnabled"> <int value="0" label="Enabled"/> <int value="1" label="SBER Disabled"/> <int value="2" label="Recently sent logs"/> </enum> -<enum name="SoftwareReporterLogsUploadResult" type="int"> +<enum name="SoftwareReporterLogsUploadResult"> <int value="0" label="Success"/> <int value="1" label="Request failed"/> <int value="2" label="Invalid response"/> @@ -33819,35 +33823,35 @@ <int value="6" label="No network"/> </enum> -<enum name="SoftwareReporterLogsUploadResultRegistryError" type="int"> +<enum name="SoftwareReporterLogsUploadResultRegistryError"> <int value="0" label="No error"/> <int value="1" label="Invalid registry key"/> <int value="2" label="Value not found"/> <int value="3" label="Value out of bounds"/> </enum> -<enum name="SpareWebContentsStatus" type="int"> +<enum name="SpareWebContentsStatus"> <int value="0" label="Created"/> <int value="1" label="Used"/> <int value="2" label="Render process gone"/> <int value="3" label="Destroyed"/> </enum> -<enum name="SpdyFrameFlowControlState" type="int"> +<enum name="SpdyFrameFlowControlState"> <int value="0" label="Send not stalled"/> <int value="1" label="Send stalled by stream"/> <int value="2" label="Send stalled by session"/> <int value="3" label="Send stalled by stream and session"/> </enum> -<enum name="SpdyIPPoolDomainMatch" type="int"> +<enum name="SpdyIPPoolDomainMatch"> <int value="0" label="mismatch"/> <int value="1" label="match"/> </enum> <!-- Replaced by SpdyProtocolErrorDetails2 on 2013-04-19. --> -<enum name="SpdyProtocolErrorDetails" type="int"> +<enum name="SpdyProtocolErrorDetails"> <int value="0" label="No error"/> <int value="1" label="Invalid Control Frame"/> <int value="2" label="Control Frame Payload Too Large"/> @@ -33880,7 +33884,7 @@ <int value="26" label="Num Spdy Protocol Error Details"/> </enum> -<enum name="SpdyProtocolErrorDetails2" type="int"> +<enum name="SpdyProtocolErrorDetails2"> <!-- SpdyFramer::SpdyErrors --> <int value="0" label="No error"/> @@ -33942,7 +33946,7 @@ <int value="42" label="Compression error."/> </enum> -<enum name="SpdyProtocolVersion" type="int"> +<enum name="SpdyProtocolVersion"> <summary> SPDY protocol version identifier, including major and minor protocol numbers, and draft versions where appropriate. @@ -33957,31 +33961,31 @@ <int value="7" label="HTTP/2"/> </enum> -<enum name="SpdySessionGet" type="int"> +<enum name="SpdySessionGet"> <int value="0" label="created new"/> <int value="1" label="found existing"/> <int value="2" label="found existing from IP Pool"/> <int value="3" label="imported from socket"/> </enum> -<enum name="SpdySettingsReceived" type="int"> +<enum name="SpdySettingsReceived"> <int value="0" label="not received"/> <int value="1" label="received"/> </enum> -<enum name="SpdySettingsSent" type="int"> +<enum name="SpdySettingsSent"> <int value="0" label="not sent"/> <int value="1" label="sent"/> </enum> -<enum name="SpecialLocalePromoAction" type="int"> +<enum name="SpecialLocalePromoAction"> <int value="0" label="Use Sogou"/> <int value="1" label="Keep Google"/> <int value="2" label="Settings"/> <int value="3" label="Back key"/> </enum> -<enum name="SpecialShFileOperationCodes" type="int"> +<enum name="SpecialShFileOperationCodes"> <summary>Legacy error codes still returned by |ShFileOperation()|</summary> <int value="5" label="Access denied (Win32)"/> <int value="32" label="Sharing violation (Win32)"/> @@ -34013,44 +34017,44 @@ <int value="65652" label="Destination root"/> </enum> -<enum name="SpeculativeRestoreApplicability" type="int"> +<enum name="SpeculativeRestoreApplicability"> <int value="0" label="Applicable"/> <int value="1" label="Not applicable (tablet)"/> <int value="2" label="Not applicable (low-memory device)"/> <int value="3" label="Not applicable (bandwidth management)"/> </enum> -<enum name="SpeculativeRestorePredictionAccuracy" type="int"> +<enum name="SpeculativeRestorePredictionAccuracy"> <int value="0" label="Hit"/> <int value="1" label="Miss (different tab)"/> <int value="2" label="Miss (tab not switched)"/> </enum> -<enum name="SpeculativeRestoreTabStatus" type="int"> +<enum name="SpeculativeRestoreTabStatus"> <int value="0" label="Already loaded"/> <int value="1" label="Needs restore"/> </enum> -<enum name="SplashscreenColorStatus" type="int"> +<enum name="SplashscreenColorStatus"> <int value="0" label="Default color"/> <int value="1" label="Custom color"/> </enum> -<enum name="SplashscreenHidesReason" type="int"> +<enum name="SplashscreenHidesReason"> <int value="0" label="First Paint"/> <int value="1" label="Page Load Finished"/> <int value="2" label="Page Load Failed"/> <int value="3" label="Crash"/> </enum> -<enum name="SplashscreenIconType" type="int"> +<enum name="SplashscreenIconType"> <int value="0" label="No splashscreen icon"/> <int value="1" label="Fallback icon"/> <int value="2" label="Custom icon"/> <int value="3" label="Small custom icon"/> </enum> -<enum name="SqliteErrorCode" type="int"> +<enum name="SqliteErrorCode"> <summary>Error codes returned by SQLite - see sqlite3.h</summary> <int value="0" label="SQLITE_OK">Successful result</int> <int value="1" label="SQLITE_ERROR">SQL error or missing database</int> @@ -34194,7 +34198,7 @@ <int value="6666" label="SQLITE_IOERR_CONVPATH">TBD</int> </enum> -<enum name="SqliteIOERRCode" type="int"> +<enum name="SqliteIOERRCode"> <obsolete> Replaced 5/14/2013 by expanded Sqlite.Error histogram. </obsolete> @@ -34236,7 +34240,7 @@ <int value="20" label="SQLITE_IOERR_SHMLOCK">Unused</int> </enum> -<enum name="SqliteRecoveryEventEnum" type="int"> +<enum name="SqliteRecoveryEventEnum"> <summary> Track successful completion or failure of sql::Recovery implementation. </summary> @@ -34345,7 +34349,7 @@ </int> </enum> -<enum name="SqliteStatsEnum" type="int"> +<enum name="SqliteStatsEnum"> <summary/> <int value="0" label="EVENT_STATEMENT_RUN"> Count statements initiated by Step(), Run(), or Execute*(). @@ -34401,7 +34405,7 @@ </int> </enum> -<enum name="SqliteVersionDeprecation" type="int"> +<enum name="SqliteVersionDeprecation"> <summary>Sqlite database version deprecation status</summary> <int value="0" label="DEPRECATION_DATABASE_NOT_EMPTY"> Database has tables, but no meta table. @@ -34419,7 +34423,7 @@ <int value="5" label="DEPRECATION_RAZE_FAILED">Raze failed.</int> </enum> -<enum name="SqliteVfsEvents" type="int"> +<enum name="SqliteVfsEvents"> <summary>I/O events from browser-process SQLite VFS wrapper.</summary> <int value="0" label="VFS_OPEN">Calls to xOpen().</int> <int value="1" label="VFS_DELETE">Calls to xDelete().</int> @@ -34434,18 +34438,18 @@ <int value="10" label="VFS_IO_FETCH">Calls to xFetch().</int> </enum> -<enum name="SRIResourceIntegrityMismatchEvent" type="int"> +<enum name="SRIResourceIntegrityMismatchEvent"> <int value="0" label="CHECKING_FOR_INTEGRITY_MISMATCH"/> <int value="1" label="REFETCH_DUE_TO_INTEGRITY_MISMATCH"/> </enum> -<enum name="SRTCompleted" type="int"> +<enum name="SRTCompleted"> <int value="0" label="Not Completed"/> <int value="1" label="Completed"/> <int value="2" label="Completed Later"/> </enum> -<enum name="SRTPromptUsage" type="int"> +<enum name="SRTPromptUsage"> <int value="0" label="Shown"/> <int value="1" label="Accepted"/> <int value="2" label="Denied"/> @@ -34455,7 +34459,7 @@ <int value="6" label="Shown from menu."/> </enum> -<enum name="SSLAuthRootConsistency" type="int"> +<enum name="SSLAuthRootConsistency"> <summary> The results of comparing the built-in list of known Windows roots against programatically detecting the built-in status. @@ -34478,7 +34482,7 @@ </int> </enum> -<enum name="SSLCaptivePortal" type="int"> +<enum name="SSLCaptivePortal"> <int value="0" label="All captive portal events (CAPTIVE_PORTAL_ALL)"/> <int value="1" label="Chrome captive portal detection enabled @@ -34517,7 +34521,7 @@ </int> </enum> -<enum name="SSLCipherSuite" type="int"> +<enum name="SSLCipherSuite"> <summary>SSL/TLS cipher suites from the IANA registry</summary> <int value="10" label="TLS_RSA_WITH_3DES_EDE_CBC_SHA"/> <int value="22" label="TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"/> @@ -34569,7 +34573,7 @@ <int value="52393" label="TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"/> </enum> -<enum name="SSLErrorCauses" type="int"> +<enum name="SSLErrorCauses"> <int value="0" label="CLOCK_PAST: System clock set early"> This cause is recorded if the SSL error is CERT_DATE_INVALID and Chrome had reason to believe that the system clock was behind. Methods of detecting @@ -34668,7 +34672,7 @@ </int> </enum> -<enum name="SSLErrorHandlerEvent" type="int"> +<enum name="SSLErrorHandlerEvent"> <int value="0" label="HANDLE_ALL"/> <int value="1" label="SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE"/> <int value="2" label="SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE"/> @@ -34682,7 +34686,7 @@ <int value="10" label="WWW_MISMATCH_FOUND_IN_SAN"/> </enum> -<enum name="SSLErrorTypes" type="int"> +<enum name="SSLErrorTypes"> <int value="0" label="CERT_COMMON_NAME_INVALID"/> <int value="1" label="CERT_DATE_INVALID"/> <int value="2" label="CERT_AUTHORITY_INVALID"/> @@ -34700,7 +34704,7 @@ <int value="14" label="CERT_VALIDITY_TOO_LONG"/> </enum> -<enum name="SSLFailureState" type="int"> +<enum name="SSLFailureState"> <obsolete> Removed June 2016. </obsolete> @@ -34713,12 +34717,12 @@ <int value="6" label="Failed with Next Proto Negotiation"/> </enum> -<enum name="SSLGoodCertSeenEvent" type="int"> +<enum name="SSLGoodCertSeenEvent"> <int value="0" label="NO_PREVIOUS_EXCEPTION"/> <int value="1" label="HAD_PREVIOUS_EXCEPTION"/> </enum> -<enum name="SSLHashAlgorithm" type="int"> +<enum name="SSLHashAlgorithm"> <obsolete> Removed June 2016. </obsolete> @@ -34731,20 +34735,20 @@ <int value="6" label="SHA-512"/> </enum> -<enum name="SSLIsExpiredAndDecision" type="int"> +<enum name="SSLIsExpiredAndDecision"> <int value="0" label="EXPIRED_AND_PROCEED"/> <int value="1" label="EXPIRED_AND_DO_NOT_PROCEED"/> <int value="2" label="NOT_EXPIRED_AND_PROCEED"/> <int value="3" label="NOT_EXPIRED_AND_DO_NOT_PROCEED"/> </enum> -<enum name="SSLNegotiatedAlpnProtocol" type="int"> +<enum name="SSLNegotiatedAlpnProtocol"> <int value="0" label="ALPN not used"/> <int value="1" label="HTTP/1.1 negotiated via ALPN"/> <int value="2" label="HTTP/2 negotiated via ALPN"/> </enum> -<enum name="SSLOrQUICVersion" type="int"> +<enum name="SSLOrQUICVersion"> <int value="0" label="Unknown"/> <int value="1" label="SSL 2.0"/> <int value="2" label="SSL 3.0"/> @@ -34755,7 +34759,7 @@ <int value="7" label="QUIC"/> </enum> -<enum name="SSLProtocolNegotiation" type="int"> +<enum name="SSLProtocolNegotiation"> <int value="1" label="ALPN, HTTP/1.1"/> <int value="100" label="ALPN, SPDY 2.0"/> <int value="101" label="ALPN, SPDY 3.0"/> @@ -34782,7 +34786,7 @@ <int value="1200" label="NPN, fallback to QUIC/1 + SPDY/3"/> </enum> -<enum name="SSLResponseTypesV2" type="int"> +<enum name="SSLResponseTypesV2"> <int value="0" label="SHOW_ALL"/> <int value="1" label="SHOW_OVERRIDABLE"/> <int value="2" label="PROCEED_OVERRIDABLE"/> @@ -34834,7 +34838,7 @@ label="Displayed clock interstitial. (DISPLAYED_CLOCK_INTERSTITIAL)"/> </enum> -<enum name="SSLSignatureAlgorithm" type="int"> +<enum name="SSLSignatureAlgorithm"> <int value="513" label="rsa_pkcs1_sha1"/> <int value="515" label="ecdsa_sha1"/> <int value="1025" label="rsa_pkcs1_sha256"/> @@ -34851,7 +34855,7 @@ <int value="2054" label="rsa_pss_sha512"/> </enum> -<enum name="StarsLaunchLocation" type="int"> +<enum name="StarsLaunchLocation"> <int value="0" label="All Items"/> <int value="1" label="Uncategorized"/> <int value="2" label="Folder"/> @@ -34861,7 +34865,7 @@ <int value="6" label="Omnibox"/> </enum> -<enum name="StartupProfilingFinishReason" type="int"> +<enum name="StartupProfilingFinishReason"> <int value="0" label="Done (all metrics gathered)"/> <int value="1" label="Abandoned because blocking UI was displayed on startup"/> @@ -34874,19 +34878,19 @@ resource"/> </enum> -<enum name="StartupTemperature" type="int"> +<enum name="StartupTemperature"> <int value="0" label="Cold startup (mostly hard faults)"/> <int value="1" label="Warm startup (nearly no hard faults)"/> <int value="2" label="Lukewarm startup (in between cold and warm)"/> </enum> -<enum name="StartupURLsMigration" type="int"> +<enum name="StartupURLsMigration"> <int value="0" label="Performed migration"/> <int value="1" label="No migration value"/> <int value="2" label="Reset migration"/> </enum> -<enum name="State" type="int"> +<enum name="State"> <int value="0" label="Canceled"/> <int value="1" label="Dropped"/> <int value="2" label="Created"/> @@ -34899,7 +34903,7 @@ <int value="9" label="Failed"/> </enum> -<enum name="StateStoreInitResult" type="int"> +<enum name="StateStoreInitResult"> <int value="0" label="Kept pref: platform-specific store non-existent or not supported."/> @@ -34908,25 +34912,25 @@ <int value="3" label="No pref change: was equal to platform-specific store"/> </enum> -<enum name="StatusHeader" type="int"> +<enum name="StatusHeader"> <int value="0" label="Headers do not include :status header field."/> <int value="1" label=":status header does not start with a number."/> <int value="2" label=":status header is an integer."/> <int value="3" label=":status header is an integer followed by text."/> </enum> -<enum name="StayVsLeave" type="int"> +<enum name="StayVsLeave"> <int value="0" label="Stay on the current page"/> <int value="1" label="Leave the current page"/> </enum> -<enum name="StyleSheetCacheStatus" type="int"> +<enum name="StyleSheetCacheStatus"> <int value="0" label="No usable cache found"/> <int value="1" label="DiskCache served the CSS source"/> <int value="2" label="MemoryCached StyleSheetContents was reused"/> </enum> -<enum name="SubmissionIndicatorEvent" type="int"> +<enum name="SubmissionIndicatorEvent"> <int value="0" label="No submission"/> <int value="1" label="HTML form submission"/> <int value="2" label="Same document navigation"/> @@ -34939,14 +34943,14 @@ <int value="9" label="Filled input elements on start provisional load"/> </enum> -<enum name="SubmittedPasswordFormFrame" type="int"> +<enum name="SubmittedPasswordFormFrame"> <int value="0" label="Main frame"/> <int value="1" label="Iframe with the same url as main frame"/> <int value="2" label="Iframe with different url and the same signon realm"/> <int value="3" label="Iframe with different signon realm"/> </enum> -<enum name="SubresourceFilterActions" type="int"> +<enum name="SubresourceFilterActions"> <int value="0" label="New Navigation"/> <int value="1" label="UI Shown"/> <int value="2" label="Details shown"/> @@ -34961,7 +34965,7 @@ <int value="11" label="Content setting: allowed while UI suppressed"/> </enum> -<enum name="SubresourceFilterActivationDecision" type="int"> +<enum name="SubresourceFilterActivationDecision"> <int value="0" label="Unknown"/> <int value="1" label="Activated"/> <int value="2" label="Disabled"/> @@ -34970,13 +34974,13 @@ <int value="5" label="Activation conditions not met"/> </enum> -<enum name="SubresourceFilterActivationState" type="int"> +<enum name="SubresourceFilterActivationState"> <int value="0" label="Disabled"/> <int value="1" label="DryRun"/> <int value="2" label="Enabled"/> </enum> -<enum name="SubresourceFilterMatchPattern" type="int"> +<enum name="SubresourceFilterMatchPattern"> <int value="0" label="NoHit"/> <int value="1" label="Last"/> <int value="2" label="Middle"/> @@ -34988,7 +34992,7 @@ <int value="8" label="NoRedirectsHit"/> </enum> -<enum name="SubresourceFilterWriteRulesetResult" type="int"> +<enum name="SubresourceFilterWriteRulesetResult"> <int value="0" label="Success"/> <int value="1" label="FailedCreatingScratchDir"/> <int value="2" label="FailedWritingRulesetData"/> @@ -35003,26 +35007,26 @@ <int value="11" label="AbortedBecauseSentinelFileWasPresent"/> </enum> -<enum name="SuggestAppsDialogCloseReason" type="int"> +<enum name="SuggestAppsDialogCloseReason"> <int value="0" label="Unknown error"/> <int value="1" label="Item installed"/> <int value="2" label="User cancelled"/> <int value="3" label="Webstore link clicked"/> </enum> -<enum name="SuggestAppsDialogInstall" type="int"> +<enum name="SuggestAppsDialogInstall"> <int value="0" label="Install succeeded"/> <int value="1" label="Install cancelled"/> <int value="2" label="Install failed"/> </enum> -<enum name="SuggestAppsDialogLoad" type="int"> +<enum name="SuggestAppsDialogLoad"> <int value="0" label="Load succeeded"/> <int value="1" label="Load cancelled"/> <int value="2" label="Load failed"/> </enum> -<enum name="SuggestionAnswerType" type="int"> +<enum name="SuggestionAnswerType"> <summary>Type of Answer shown in omnibox suggestion list.</summary> <int value="1" label="Dictionary"/> <int value="2" label="Finance"/> @@ -35035,13 +35039,13 @@ <int value="10" label="Currency"/> </enum> -<enum name="SuggestionsResponseState" type="int"> +<enum name="SuggestionsResponseState"> <int value="0" label="Empty response received from the server."/> <int value="1" label="Invalid response received from the server."/> <int value="2" label="Valid response received from the server."/> </enum> -<enum name="SupervisedUserSafetyFilterResult" type="int"> +<enum name="SupervisedUserSafetyFilterResult"> <int value="100" label="LINK_ALLOWED">Link; Allowed as safe</int> <int value="101" label="TYPED_ALLOWED">Typed URL; Allowed as safe</int> <int value="102" label="AUTO_BOOKMARK_ALLOWED">Bookmark; Allowed as safe</int> @@ -35287,30 +35291,30 @@ </int> </enum> -<enum name="SuspendAttempt" type="int"> +<enum name="SuspendAttempt"> <int value="0" label="Attempted"/> </enum> -<enum name="SuspendResult" type="int"> +<enum name="SuspendResult"> <int value="0" label="Succeeded"/> <int value="1" label="Failed"/> <int value="2" label="Canceled (before writing wakeup count)"/> <int value="3" label="Canceled (after writing wakeup count)"/> </enum> -<enum name="SuspendStatus" type="int"> +<enum name="SuspendStatus"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Cancelled"/> <int value="3" label="Attempted"/> </enum> -<enum name="SwapchainFormat" type="int"> +<enum name="SwapchainFormat"> <int value="0" label="B8G8R8A8"/> <int value="1" label="YUY2"/> </enum> -<enum name="SwReporterRunningTimeRegistryError" type="int"> +<enum name="SwReporterRunningTimeRegistryError"> <int value="0" label="No error"/> <int value="1" label="Registry key invalid"/> <int value="2" label="Missing start time"/> @@ -35318,7 +35322,7 @@ <int value="4" label="Missing start and end times"/> </enum> -<enum name="SwReporterStep" type="int"> +<enum name="SwReporterStep"> <int value="0" label="Explicit request"/> <int value="1" label="Startup retry"/> <int value="2" label="Retried too many times"/> @@ -35336,26 +35340,26 @@ <int value="14" label="Added to menu"/> </enum> -<enum name="SyncAttachmentStoreResult" type="int"> +<enum name="SyncAttachmentStoreResult"> <int value="0" label="SUCCESS"/> <int value="1" label="UNSPECIFIED_ERROR"/> <int value="2" label="STORE_INITIALIZATION_FAILED"/> </enum> -<enum name="SyncAuthError" type="int"> +<enum name="SyncAuthError"> <int value="0" label="Number of times clients have encountered an Auth error."/> <int value="1" label="Number of times clients have fixed an auth error."/> </enum> -<enum name="SyncBackendInitializeRestoreState" type="int"> +<enum name="SyncBackendInitializeRestoreState"> <int value="0" label="Expected restored types and found some"/> <int value="1" label="Expected restored types but found none"/> <int value="2" label="Did not expect restored types and found none"/> <int value="3" label="Did not expect restored types but found some"/> </enum> -<enum name="SyncBookmarkModelSyncState" type="int"> +<enum name="SyncBookmarkModelSyncState"> <summary> The state of the local bookmark model version compared to Sync. Corresponds to NativeModelSyncState in bookmark_model_associator.h. @@ -35366,7 +35370,7 @@ <int value="3" label="Local version is ahead"/> </enum> -<enum name="SyncConfigureResult" type="int"> +<enum name="SyncConfigureResult"> <summary> Sync data type configure results. The codes are listed in data_type_controller.h with more details. @@ -35380,7 +35384,7 @@ <int value="6" label="RUNTIME_ERROR"/> </enum> -<enum name="SyncConflictResolutions" type="int"> +<enum name="SyncConflictResolutions"> <summary> Sync conflict resolutions. The codes are listed in conflict_resolution.h, and correspond to all the different ways a sync conflict can be resolved. @@ -35391,34 +35395,34 @@ <int value="3" label="Use new"/> </enum> -<enum name="SyncCryptographerPendingKeysState" type="int"> +<enum name="SyncCryptographerPendingKeysState"> <int value="0" label="Does not have pending keys"/> <int value="1" label="Has pending keys"/> </enum> -<enum name="SyncCryptographerReadyState" type="int"> +<enum name="SyncCryptographerReadyState"> <int value="0" label="Not Ready"/> <int value="1" label="Ready"/> </enum> -<enum name="SyncCustomEncryptionEvent" type="int"> +<enum name="SyncCustomEncryptionEvent"> <int value="0" label="Default setup with an implicit passphrase"/> <int value="1" label="Advanced setup with a custom passphrase"/> </enum> -<enum name="SyncDeferredInitTrigger" type="int"> +<enum name="SyncDeferredInitTrigger"> <int value="0" label="Data type requested init."/> <int value="1" label="Fallback timer triggered init."/> </enum> -<enum name="SyncDirectoryOpenResult" type="int"> +<enum name="SyncDirectoryOpenResult"> <summary>Possible outcomes of an attempt to load the sync directory.</summary> <int value="0" label="FIRST_TRY_SUCCESS"/> <int value="1" label="SECOND_TRY_SUCCESS"/> <int value="2" label="SECOND_TRY_FAILURE"/> </enum> -<enum name="SyncedNotificationActionType" type="int"> +<enum name="SyncedNotificationActionType"> <int value="0" label="Unknown"/> <int value="1" label="Notification clicked"/> <int value="2" label="Notification button clicked"/> @@ -35426,14 +35430,14 @@ <int value="4" label="Notification closed by system"/> </enum> -<enum name="SyncedSearchEngineDeleteEvent" type="int"> +<enum name="SyncedSearchEngineDeleteEvent"> <summary>Possible events that delete a synced search engine.</summary> <int value="0" label="USER_INITIATED"/> <int value="1" label="PRE_SYNC_DELETE"/> <int value="2" label="EMPTY_FIELD"/> </enum> -<enum name="SyncErrorInfobarTypes" type="int"> +<enum name="SyncErrorInfobarTypes"> <summary>Possible errors that can trigger a sync error infobar.</summary> <int value="1" label="Sign in needs update"/> <int value="2" label="Service unavailable"/> @@ -35441,7 +35445,7 @@ <int value="4" label="Unrecoverable error"/> </enum> -<enum name="SyncEventCode" type="int"> +<enum name="SyncEventCode"> <summary> Sync UI events. The codes are listed in profile_syncer_service.h with more details. @@ -35457,25 +35461,25 @@ <int value="30" label="MERGE_AND_SYNC_NEEDED"/> </enum> -<enum name="SyncFaviconsAvailable" type="int"> +<enum name="SyncFaviconsAvailable"> <int value="0" label="Synced favicons full"/> <int value="1" label="Synced favicons not full"/> </enum> -<enum name="SyncFSConflictResolutionPolicy" type="int"> +<enum name="SyncFSConflictResolutionPolicy"> <int value="0" label="Unknown"/> <int value="1" label="LastWriteWin"/> <int value="2" label="Manual"/> </enum> -<enum name="SyncFSRemoteServiceState" type="int"> +<enum name="SyncFSRemoteServiceState"> <int value="0" label="OK"/> <int value="1" label="TemporaryUnavailable"/> <int value="2" label="AuthenticationRequired"/> <int value="3" label="Disabled"/> </enum> -<enum name="SyncInitialState" type="int"> +<enum name="SyncInitialState"> <int value="0" label="Can attempt to start"/> <int value="1" label="No signed in user"/> <int value="2" label="Turned off by user"/> @@ -35485,12 +35489,12 @@ <int value="6" label="Disallowed by the platform"/> </enum> -<enum name="SyncKeystoreDecryptionFailure" type="int"> +<enum name="SyncKeystoreDecryptionFailure"> <int value="0" label="No keystore key"/> <int value="1" label="Unknown reason"/> </enum> -<enum name="SyncModelTypes" type="int"> +<enum name="SyncModelTypes"> <int value="0" label="Unspecified"/> <int value="1" label="Top Level Folder"/> <int value="2" label="Bookmarks"/> @@ -35533,7 +35537,7 @@ <int value="39" label="User Events"/> </enum> -<enum name="SyncModelTypeStoreInitResult" type="int"> +<enum name="SyncModelTypeStoreInitResult"> <int value="0" label="Success"/> <int value="1" label="Not found"/> <int value="2" label="Corruption"/> @@ -35546,7 +35550,7 @@ <int value="9" label="Store recovered after corruption"/> </enum> -<enum name="SyncNigoriMigrationResult" type="int"> +<enum name="SyncNigoriMigrationResult"> <int value="0" label="Failed to set default encryption key"/> <int value="1" label="Failed to set nondefault encryption key"/> <int value="2" label="Failed to extract keystore decryptor"/> @@ -35559,33 +35563,33 @@ <int value="7" label="Successfully migrated with custom passphrase"/> </enum> -<enum name="SyncNigoriMigrationState" type="int"> +<enum name="SyncNigoriMigrationState"> <int value="0" label="Fully migrated"/> <int value="1" label="Not migrated due to cryptographer not ready"/> <int value="2" label="Not migrated due to missing keystore key"/> <int value="3" label="Not migrated for an unknown reason"/> </enum> -<enum name="SyncPassphraseDismissal" type="int"> +<enum name="SyncPassphraseDismissal"> <int value="0" label="Passphrase accepted"/> <int value="1" label="Cancel with wrong passphrase error"/> <int value="2" label="Cancel without any passphrase attempted"/> <int value="3" label="Followed reset link"/> </enum> -<enum name="SyncPassphraseType" type="int"> +<enum name="SyncPassphraseType"> <int value="0" label="IMPLICIT_PASSPHRASE"/> <int value="1" label="KEYSTORE_PASSPHRASE"/> <int value="2" label="FROZEN_IMPLICIT_PASSPHRASE"/> <int value="3" label="CUSTOM_PASSPHRASE"/> </enum> -<enum name="SyncPromoAction" type="int"> +<enum name="SyncPromoAction"> <int value="0" label="The promo was shown to the user"/> <int value="1" label="The user clicked the promo to sign in"/> </enum> -<enum name="SyncSimpleConflictResolutions" type="int"> +<enum name="SyncSimpleConflictResolutions"> <summary> Sync simple conflict resolutions. The codes are listed in conflict_resolver.h, and correspond to the different methods we have for @@ -35599,7 +35603,7 @@ <int value="5" label="Changes match"/> </enum> -<enum name="SyncStartResult" type="int"> +<enum name="SyncStartResult"> <summary> Sync data type start results. The codes are listed in data_type_controller.h with more details. @@ -35614,7 +35618,7 @@ <int value="7" label="NEEDS_CRYPTO"/> </enum> -<enum name="SyncStopSource" type="int"> +<enum name="SyncStopSource"> <int value="0" label="Profile destruction"/> <int value="1" label="Sign out"/> <int value="2" label="Birthday error"/> @@ -35623,7 +35627,7 @@ <int value="5" label="Android master sync setting"/> </enum> -<enum name="SyncUnrecoverableErrorReason" type="int"> +<enum name="SyncUnrecoverableErrorReason"> <summary>Reasons for sync unrecoverable errors.</summary> <int value="0" label="No error"/> <int value="1" label="Syncer error"/> @@ -35633,7 +35637,7 @@ <int value="5" label="Actionable error"/> </enum> -<enum name="SystemLogPIIType" type="int"> +<enum name="SystemLogPIIType"> <obsolete> Deprecated and removed from code as of 01/2016. </obsolete> @@ -35643,7 +35647,7 @@ <int value="3" label="SSID"/> </enum> -<enum name="SystemMenuDefaultViewRows" type="int"> +<enum name="SystemMenuDefaultViewRows"> <int value="0" label="NOT_RECORDED - Should not be recorded"/> <int value="1" label="TEST - Should not be recorded"/> <int value="2" label="Accessibility"/> @@ -35672,7 +35676,7 @@ <int value="25" label="VPN"/> </enum> -<enum name="SystemNotificationType" type="int"> +<enum name="SystemNotificationType"> <int value="0" label="Downloads - Files"/> <int value="1" label="Downloads - Pages"/> <int value="2" label="Close Incognito Tabs"/> @@ -35686,13 +35690,13 @@ <int value="10" label="Browser Actions"/> </enum> -<enum name="TabBackgroundLoadStatus" type="int"> +<enum name="TabBackgroundLoadStatus"> <int value="0" label="Loaded on creation and shown"/> <int value="1" label="Loaded on creation and lost"/> <int value="2" label="Not loaded on creation"/> </enum> -<enum name="TabDiscardingEvents" type="int"> +<enum name="TabDiscardingEvents"> <int value="0" label="Switched to an active tab"/> <int value="1" label="Switched to a discarded tab"/> <int value="2" label="Discarded a tab"/> @@ -35700,13 +35704,13 @@ label="Discarded a tab playing audio (included in the previous one)"/> </enum> -<enum name="TabRendererCrashStatus" type="int"> +<enum name="TabRendererCrashStatus"> <int value="0" label="Shown in foreground app"/> <int value="1" label="Hidden in foreground app"/> <int value="2" label="Hidden in background app"/> </enum> -<enum name="TabRendererExitStatus" type="int"> +<enum name="TabRendererExitStatus"> <int value="0" label="OOM protected in running app"/> <int value="1" label="OOM protected in paused app"/> <int value="2" label="OOM protected in background app"/> @@ -35715,19 +35719,19 @@ <int value="5" label="Not protected in background app"/> </enum> -<enum name="TabRestoreResult" type="int"> +<enum name="TabRestoreResult"> <int value="0" label="Failure (other)"/> <int value="1" label="Success"/> <int value="2" label="Failure due to network connectivity"/> </enum> -<enum name="TabRestoreUserAction" type="int"> +<enum name="TabRestoreUserAction"> <int value="0" label="Wait for completion"/> <int value="1" label="Leave tab (close tab/switch tab/go to tab switcher)"/> <int value="2" label="Leave Chrome"/> </enum> -<enum name="TabStatus" type="int"> +<enum name="TabStatus"> <int value="0" label="Memory resident"/> <int value="1" label="Evicted and reloaded"/> <int value="2" label="Reloaded due to cold start"/> @@ -35742,7 +35746,7 @@ <int value="11" label="Evicted due to OS terminating the renderer."/> </enum> -<enum name="TabStripState" type="int"> +<enum name="TabStripState"> <int value="0" label="Initial state"/> <int value="1" label="Tab is active, shown foreground."/> <int value="2" label="Tab is inactive, in background."/> @@ -35750,7 +35754,7 @@ <int value="4" label="Tab is closed."/> </enum> -<enum name="TabSwitchedToForegroundLaunchedWithURL" type="int"> +<enum name="TabSwitchedToForegroundLaunchedWithURL"> <obsolete> Deprecated as of 04/2014. </obsolete> @@ -35758,7 +35762,7 @@ <int value="1" label="Launched with an URL"/> </enum> -<enum name="TabSwitchedToForegroundRevisit" type="int"> +<enum name="TabSwitchedToForegroundRevisit"> <obsolete> Deprecated as of 04/2014. </obsolete> @@ -35766,12 +35770,12 @@ <int value="1" label="Revisit"/> </enum> -<enum name="TapDelayType" type="int"> +<enum name="TapDelayType"> <int value="0" label="Delayed Tap"/> <int value="1" label="Undelayed Tap"/> </enum> -<enum name="TapDisambiguation" type="int"> +<enum name="TapDisambiguation"> <int value="0" label="Other"/> <int value="1" label="Back Button"/> <int value="2" label="Tapped Outside"/> @@ -35780,7 +35784,7 @@ <int value="5" label="Tapped Inside, Different Node"/> </enum> -<enum name="TcpSocketStatus" type="int"> +<enum name="TcpSocketStatus"> <int value="0" label="Unknown"/> <int value="1" label="Fast Connection Return"/> <int value="2" label="Slow Connection Return"/> @@ -35796,7 +35800,7 @@ <int value="12" label="Previously Failed"/> </enum> -<enum name="TempFileFailure" type="int"> +<enum name="TempFileFailure"> <int value="0" label="Creating"/> <int value="1" label="Opening"/> <int value="2" label="Closing (unused)"/> @@ -35805,7 +35809,7 @@ <int value="5" label="Flushing"/> </enum> -<enum name="TerminationStatus" type="int"> +<enum name="TerminationStatus"> <summary> Return status values from GetTerminationStatus as defined in base/process/kill.h enum TerminationStatus. The last couple enums are @@ -35830,7 +35834,7 @@ </int> </enum> -<enum name="TextToSpeechEvent" type="int"> +<enum name="TextToSpeechEvent"> <int value="0" label="Start"/> <int value="1" label="End"/> <int value="2" label="Word"/> @@ -35843,64 +35847,64 @@ <int value="9" label="Resume"/> </enum> -<enum name="TextToSpeechFromExtensionAPI" type="int"> +<enum name="TextToSpeechFromExtensionAPI"> <int value="0" label="Web speech API"/> <int value="1" label="Chrome TTS extension API"/> </enum> -<enum name="TextToSpeechHasGender" type="int"> +<enum name="TextToSpeechHasGender"> <int value="0" label="Does Not Have Gender"/> <int value="1" label="Has Gender"/> </enum> -<enum name="TextToSpeechHasLang" type="int"> +<enum name="TextToSpeechHasLang"> <int value="0" label="Does Not Have Language"/> <int value="1" label="Has Language"/> </enum> -<enum name="TextToSpeechHasPitch" type="int"> +<enum name="TextToSpeechHasPitch"> <int value="0" label="Does Not Have Pitch"/> <int value="1" label="Has Pitch"/> </enum> -<enum name="TextToSpeechHasRate" type="int"> +<enum name="TextToSpeechHasRate"> <int value="0" label="Does Not Have Rate"/> <int value="1" label="Has Rate"/> </enum> -<enum name="TextToSpeechHasVoiceName" type="int"> +<enum name="TextToSpeechHasVoiceName"> <int value="0" label="Does Not Have Voice Name"/> <int value="1" label="Has Voice Name"/> </enum> -<enum name="TextToSpeechHasVolume" type="int"> +<enum name="TextToSpeechHasVolume"> <int value="0" label="Does Not Have Volume"/> <int value="1" label="Has Volume"/> </enum> -<enum name="TextToSpeechNative" type="int"> +<enum name="TextToSpeechNative"> <int value="0" label="Extension Speech"/> <int value="1" label="Native Speech"/> </enum> -<enum name="ThreadType" type="int"> +<enum name="ThreadType"> <int value="0" label="UI"/> <int value="1" label="Blocking"/> </enum> -<enum name="ThrottleInfobarResponse" type="int"> +<enum name="ThrottleInfobarResponse"> <int value="0" label="No response"/> <int value="1" label="Try again"/> <int value="2" label="Wait"/> <int value="3" label="Infobar dismissed"/> </enum> -<enum name="TileMemoryBudget" type="int"> +<enum name="TileMemoryBudget"> <int value="0" label="Within memory budget"/> <int value="1" label="Exceeded memory budget"/> </enum> -<enum name="TimeZoneRequestEvent" type="int"> +<enum name="TimeZoneRequestEvent"> <int value="0" label="Request start"/> <int value="1" label="Response success"/> <int value="2" label="Response not OK"/> @@ -35908,19 +35912,19 @@ <int value="4" label="Response malformed"/> </enum> -<enum name="TimeZoneRequestResult" type="int"> +<enum name="TimeZoneRequestResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> <int value="2" label="Server error"/> <int value="3" label="Request is cancelled."/> </enum> -<enum name="TLSRenegotiationPatched" type="int"> +<enum name="TLSRenegotiationPatched"> <int value="0" label="Not renegotiation patched"/> <int value="1" label="Renegotiation patched"/> </enum> -<enum name="TokenBinding.KeyMatch" type="int"> +<enum name="TokenBinding.KeyMatch"> <int value="0" label="No keys"/> <int value="1" label="Keys match"/> <int value="2" label="Socket (Channel ID) key missing"/> @@ -35929,7 +35933,7 @@ <int value="5" label="Error looking up request key"/> </enum> -<enum name="TokenBinding.StoreEphemerality" type="int"> +<enum name="TokenBinding.StoreEphemerality"> <int value="0" label="CID_EPHEMERAL_COOKIE_EPHEMERAL"> This value has been deprecated and replaced by EPHEMERAL_MATCH and EPHEMERAL_MISMATCH. @@ -35951,26 +35955,26 @@ <int value="12" label="PERSISTENT_UNKNOWN"/> </enum> -<enum name="TokenBinding.Support" type="int"> +<enum name="TokenBinding.Support"> <int value="0" label="DISABLED"/> <int value="1" label="CLIENT_ONLY"/> <int value="2" label="CLIENT_AND_SERVER"/> <int value="3" label="CLIENT_NO_CHANNEL_ID_SERVICE"/> </enum> -<enum name="TouchEventDispatchResultType" type="int"> +<enum name="TouchEventDispatchResultType"> <int value="0" label="Unhandled touch events"/> <int value="1" label="Handled touch events"/> </enum> -<enum name="TouchEventFeatureDetectionState" type="int"> +<enum name="TouchEventFeatureDetectionState"> <int value="0" label="Enabled"/> <int value="1" label="Automatic - enabled"/> <int value="2" label="Automatic - disabled"/> <int value="3" label="Disabled"/> </enum> -<enum name="TouchpadDeviceState" type="int"> +<enum name="TouchpadDeviceState"> <int value="0" label="NO_TP_PRESENT_NO_TP_EXPECTED"> No touchpad detected on a device without built-in touchpad </int> @@ -35993,7 +35997,7 @@ </int> </enum> -<enum name="TouchpadProblemType" type="int"> +<enum name="TouchpadProblemType"> <int value="0" label="All events"> All observed input events from touchpad. Serves as a reference. </int> @@ -36003,7 +36007,7 @@ </int> </enum> -<enum name="TouchTargetAndDispatchResultType" type="int"> +<enum name="TouchTargetAndDispatchResultType"> <int value="0" label="Non-root-scroller, non-scrollable document, not handled"/> <int value="1" @@ -36019,7 +36023,7 @@ label="Root-scroller, scrollable document, handled application"/> </enum> -<enum name="TouchTargetAndDispatchResultType2" type="int"> +<enum name="TouchTargetAndDispatchResultType2"> <int value="0" label="Capturing Non-root-scroller, non-scrollable document, already handled"/> @@ -36102,7 +36106,7 @@ label="Bubbling Root-scroller, scrollable document, handled application"/> </enum> -<enum name="TPMResultCodeEnum" type="int"> +<enum name="TPMResultCodeEnum"> <int value="0" label="TPM_SUCCESS"/> <int value="1" label="TPM_E_AUTHFAIL"/> <int value="2" label="TPM_E_BADINDEX"/> @@ -36208,7 +36212,7 @@ <int value="2051" label="TPM_E_DEFEND_LOCK_RUNNING"/> </enum> -<enum name="TrackedPreference" type="int"> +<enum name="TrackedPreference"> <int value="0" label="kShowHomeButton"/> <int value="1" label="kHomePageIsNewTabPage"/> <int value="2" label="kHomePage"/> @@ -36240,7 +36244,7 @@ <int value="28" label="kSettingsResetPromptLastTriggeredForHomepage"/> </enum> -<enum name="TranslateBubbleUiEvent" type="int"> +<enum name="TranslateBubbleUiEvent"> <int value="1" label="Switch to Options page"/> <int value="2" label="Leave Options page"/> <int value="3" label="Advanced Link clicked"/> @@ -36268,7 +36272,7 @@ <int value="25" label="Bubble not shown: editable field is active"/> </enum> -<enum name="TranslateCompactUIEvent" type="int"> +<enum name="TranslateCompactUIEvent"> <int value="0" label="Infobar impression"/> <int value="1" label="Translation accepted by clicking on tab language"/> <int value="2" @@ -36311,7 +36315,7 @@ <int value="24" label="Cancel clicked on auto-never translate snackbar"/> </enum> -<enum name="TranslateError" type="int"> +<enum name="TranslateError"> <int value="0" label="No error"/> <int value="1" label="Network error"/> <int value="2" label="Initialization error"/> @@ -36321,7 +36325,7 @@ <int value="6" label="Translation error"/> </enum> -<enum name="TranslateInitiationStatus" type="int"> +<enum name="TranslateInitiationStatus"> <int value="0" label="Completely disabled by prefs"/> <int value="1" label="Completely disabled by switch"/> <int value="2" label="Disabled by user configuration"/> @@ -36338,19 +36342,19 @@ <int value="13" label="Aborted by translate ranker"/> </enum> -<enum name="TranslateLanguage" type="int"> +<enum name="TranslateLanguage"> <int value="0" label="No language code"/> <int value="1" label="Valid language code"/> <int value="2" label="Invalid language code"/> </enum> -<enum name="TranslateLanguageDetectionTiming" type="int"> +<enum name="TranslateLanguageDetectionTiming"> <int value="0" label="On time"/> <int value="1" label="Deferred"/> <int value="2" label="Resumed"/> </enum> -<enum name="TranslateLanguageVerification" type="int"> +<enum name="TranslateLanguageVerification"> <int value="0" label="CLD is disabled"/> <int value="1" label="No Content-Language"/> <int value="2" label="CLD can not determine a language"/> @@ -36360,13 +36364,13 @@ <int value="6" label="CLD can complement a sub code"/> </enum> -<enum name="TranslateScheme" type="int"> +<enum name="TranslateScheme"> <int value="0" label="http"/> <int value="1" label="https"/> <int value="2" label="unexpected other schemes"/> </enum> -<enum name="TriggerHelpUIResult" type="int"> +<enum name="TriggerHelpUIResult"> <int value="0" label="SUCCESS"/> <int value="1" label="FAILURE"/> <int value="2" label="FAILURE_MODEL_NOT_READY"/> @@ -36381,7 +36385,7 @@ <int value="11" label="FAILURE_AVAILABILITY_PRECONDITION_UNMET"/> </enum> -<enum name="TrimMemoryLevel" type="int"> +<enum name="TrimMemoryLevel"> <summary> The level provided by Android's ComponentCallbacks2.onTrimMemory(). </summary> @@ -36393,7 +36397,7 @@ <int value="80" label="TRIM_MEMORY_COMPLETE"/> </enum> -<enum name="UIEventType" type="int"> +<enum name="UIEventType"> <int value="0" label="Unknown"/> <int value="1" label="Touch released"/> <int value="2" label="Touch pressed"/> @@ -36433,14 +36437,14 @@ <int value="36" label="Tap unconfirmed"/> </enum> -<enum name="UkmDataDroppedReason" type="int"> +<enum name="UkmDataDroppedReason"> <int value="0" label="Not dropped"/> <int value="1" label="Recording disabled"/> <int value="2" label="Max hit"/> <int value="3" label="Not whitelisted"/> </enum> -<enum name="UmaCleanExitConsistency" type="int"> +<enum name="UmaCleanExitConsistency"> <int value="0" label="Dirty/Dirty (Registry/Local State)"/> <int value="1" label="Dirty/Clean (Registry/Local State)"/> <int value="2" label="Clean/Dirty (Registry/Local State)"/> @@ -36449,32 +36453,32 @@ <int value="5" label="Missing/Clean (Registry/Local State)"/> </enum> -<enum name="UmaEntropySourceType" type="int"> +<enum name="UmaEntropySourceType"> <int value="0" label="No entropy source (never hit)"/> <int value="1" label="Low Entropy Source"/> <int value="2" label="High Entropy Source"/> </enum> -<enum name="UmaInitSequence" type="int"> +<enum name="UmaInitSequence"> <int value="0" label="Timer fired first"/> <int value="1" label="Init task completed first"/> </enum> -<enum name="UmaMachineIdState" type="int"> +<enum name="UmaMachineIdState"> <int value="0" label="ID generation failed"/> <int value="1" label="No stored value"/> <int value="2" label="Machine ID changed"/> <int value="3" label="Machine ID unchanged"/> </enum> -<enum name="UmaUploadResponseStatus" type="int"> +<enum name="UmaUploadResponseStatus"> <int value="0" label="Unknown failure"/> <int value="1" label="Success"/> <int value="2" label="Bad request"/> <int value="3" label="No response"/> </enum> -<enum name="UncacheableReason" type="int"> +<enum name="UncacheableReason"> <int value="0" label="kNoData"/> <int value="1" label="kPre11PartialResponse"/> <int value="2" label="kNoStrongValidatorOnPartialResponse"/> @@ -36485,20 +36489,20 @@ <int value="7" label="kNoStore"/> </enum> -<enum name="UniformityTrialGroupNotActive" type="int"> +<enum name="UniformityTrialGroupNotActive"> <int value="0" label="Invalid"/> <int value="1" label="Group not reported"/> <int value="2" label="Trial was disabled"/> <int value="3" label="Group not reported and trial was disabled"/> </enum> -<enum name="UnlockType" type="int"> +<enum name="UnlockType"> <int value="0" label="Password"/> <int value="1" label="Pin"/> <int value="2" label="Fingerprint"/> </enum> -<enum name="UnPackStatus" type="int"> +<enum name="UnPackStatus"> <int value="0" label="No Error"/> <int value="1" label="Archive file not found"/> <int value="2" label="Archive file can not be opened"/> @@ -36512,7 +36516,7 @@ <int value="10" label="Can not close extracted file"/> </enum> -<enum name="UpdateEngineAttemptResult" type="int"> +<enum name="UpdateEngineAttemptResult"> <int value="0" label="Update Succeeded"/> <int value="1" label="Internal Error"/> <int value="2" label="Payload Download Error"/> @@ -36526,7 +36530,7 @@ <int value="10" label="Abnormal Termination"/> </enum> -<enum name="UpdateEngineCertificateCheckStatus" type="int"> +<enum name="UpdateEngineCertificateCheckStatus"> <int value="0" label="Valid certificate"> The certificate is valid and the same as seen before or the first time we see a certificate. @@ -36540,14 +36544,14 @@ </int> </enum> -<enum name="UpdateEngineCheckReaction" type="int"> +<enum name="UpdateEngineCheckReaction"> <int value="0" label="Updating"/> <int value="1" label="Ignoring"/> <int value="2" label="Deferring"/> <int value="3" label="Backing Off"/> </enum> -<enum name="UpdateEngineCheckResult" type="int"> +<enum name="UpdateEngineCheckResult"> <int value="0" label="Update Available"/> <int value="1" label="No Update Available"/> <int value="2" label="Response Download Error"/> @@ -36555,7 +36559,7 @@ <int value="4" label="Reboot Pending"/> </enum> -<enum name="UpdateEngineConnectionType" type="int"> +<enum name="UpdateEngineConnectionType"> <int value="0" label="Unknown"/> <int value="1" label="Ethernet"/> <int value="2" label="Wifi"/> @@ -36566,7 +36570,7 @@ <int value="7" label="Tethered (Wifi)"/> </enum> -<enum name="UpdateEngineDownloadErrorCode" type="int"> +<enum name="UpdateEngineDownloadErrorCode"> <int value="0" label="Download Error"/> <int value="100" label="Input Malformed (Internal Error)"/> <int value="101" label="Unknown HTTP Status (not 200-599)"/> @@ -36588,13 +36592,13 @@ <int value="504" label="Gateway Timeout (HTTP Status 504)"/> </enum> -<enum name="UpdateEngineDownloadSource" type="int"> +<enum name="UpdateEngineDownloadSource"> <int value="0" label="HTTPS Server"/> <int value="1" label="HTTP Server"/> <int value="2" label="HTTP Peer"/> </enum> -<enum name="UpdateEngineDownloadSources" type="int"> +<enum name="UpdateEngineDownloadSources"> <int value="0" label="Other"/> <int value="1" label="HTTPS Server Only"/> <int value="2" label="HTTP Server Only"/> @@ -36605,7 +36609,7 @@ <int value="7" label="HTTP Peer, HTTPS Server, and HTTP Server"/> </enum> -<enum name="UpdateEngineErrorCode" type="int"> +<enum name="UpdateEngineErrorCode"> <int value="0" label="kErrorCodeSuccess"/> <int value="1" label="kErrorCodeError"/> <int value="2" label="kErrorCodeOmahaRequestError"/> @@ -36659,18 +36663,18 @@ <int value="50" label="kErrorCodeOmahaUpdateIgnoredOverCellular"/> </enum> -<enum name="UpdateEngineInstallDateProvisioningSource" type="int"> +<enum name="UpdateEngineInstallDateProvisioningSource"> <int value="0" label="Omaha Response"/> <int value="1" label="OOBE Marker"/> </enum> -<enum name="UpdateEnginePayloadFormat" type="int"> +<enum name="UpdateEnginePayloadFormat"> <int value="0" label="Full"/> <int value="1" label="Delta"/> <int value="2" label="Forced Full"/> </enum> -<enum name="UpdatePasswordSubmissionEvent" type="int"> +<enum name="UpdatePasswordSubmissionEvent"> <int value="0" label="NO_ACCOUNTS_CLICKED_UPDATE"/> <int value="1" label="NO_ACCOUNTS_CLICKED_NOPE"/> <int value="2" label="NO_ACCOUNTS_NO_INTERACTION"/> @@ -36685,14 +36689,14 @@ <int value="11" label="PASSWORD_OVERRIDDEN_NO_INTERACTION"/> </enum> -<enum name="UpdatePolicy" type="int"> +<enum name="UpdatePolicy"> <int value="0" label="UPDATES_DISABLED"/> <int value="1" label="AUTOMATIC_UPDATES"/> <int value="2" label="MANUAL_UPDATES_ONLY"/> <int value="3" label="AUTO_UPDATES_ONLY"/> </enum> -<enum name="URLRequestAnnotationType" type="int"> +<enum name="URLRequestAnnotationType"> Generated by tools/traffic_annotation/auditor/traffic_annotation_auditor.py. <int value="485305" label="data_reduction_proxy_config"/> <int value="727478" label="metrics_report_ukm"/> @@ -36860,13 +36864,13 @@ <int value="137457845" label="web_history_counter"/> </enum> -<enum name="UrlResolutionResult" type="int"> +<enum name="UrlResolutionResult"> <int value="0" label="Absolute URL"/> <int value="1" label="Resolutions Differ"/> <int value="2" label="Resolutions Agree"/> </enum> -<enum name="URLSchemeForHistogram" type="int"> +<enum name="URLSchemeForHistogram"> <int value="0" label="kUnknownURLScheme"/> <int value="1" label="kMissingURLScheme"/> <int value="2" label="kHttpURLScheme"/> @@ -36880,7 +36884,7 @@ <int value="10" label="kFileSystemScheme"/> </enum> -<enum name="UsedInDraw" type="int"> +<enum name="UsedInDraw"> <obsolete> Deprecated 02/2017 in Issue 675840. </obsolete> @@ -36888,12 +36892,12 @@ <int value="1" label="Was used in draw"/> </enum> -<enum name="UserCertContentDisposition" type="int"> +<enum name="UserCertContentDisposition"> <int value="0" label="No Content-Disposition"/> <int value="1" label="Content-Disposition"/> </enum> -<enum name="UserChannels" type="int"> +<enum name="UserChannels"> <int value="-1" label="Unknown"/> <int value="0" label="Canary"/> <int value="1" label="Dev"/> @@ -36901,25 +36905,25 @@ <int value="3" label="Stable"/> </enum> -<enum name="UserGestureRequirement" type="int"> +<enum name="UserGestureRequirement"> <int value="0" label="Required and available"/> <int value="1" label="Required and not available"/> <int value="2" label="Not required and available"/> <int value="3" label="Not required and not available"/> </enum> -<enum name="UserInitiatedEvent" type="int"> +<enum name="UserInitiatedEvent"> <int value="0" label="WiFi Scan"/> </enum> -<enum name="UserPodsDisplay" type="int"> +<enum name="UserPodsDisplay"> <int value="0" label="Enabled by local settings"/> <int value="1" label="Enabled by domain policy"/> <int value="2" label="Disabled by local settings"/> <int value="3" label="Disabled by domain policy"/> </enum> -<enum name="UserSelectableSyncType" type="int"> +<enum name="UserSelectableSyncType"> <int value="0" label="Bookmarks"/> <int value="1" label="Preferences"/> <int value="2" label="Passwords"/> @@ -36934,7 +36938,7 @@ <int value="11" label="Reading List"/> </enum> -<enum name="UserType" type="int"> +<enum name="UserType"> <int value="0" label="Regular"/> <int value="1" label="Guest"/> <int value="2" label="Retail Mode"/> @@ -36944,7 +36948,7 @@ <int value="6" label="Regular Supervised"/> </enum> -<enum name="V8CodeCacheRejectReason" type="int"> +<enum name="V8CodeCacheRejectReason"> <int value="1" label="MAGIC_NUMBER_MISMATCH"> Reject due to magic number mismatch </int> @@ -36962,7 +36966,7 @@ <int value="7" label="INVALID_HEADER">Invalid header</int> </enum> -<enum name="V8DebugFeature" type="int"> +<enum name="V8DebugFeature"> <int value="1" label="kActive">Debugger has been active</int> <int value="2" label="kBreakPoint"> Debugger has been used to set break points @@ -36984,25 +36988,25 @@ </int> </enum> -<enum name="V8InitializerLoadV8SnapshotResult" type="int"> +<enum name="V8InitializerLoadV8SnapshotResult"> <int value="0" label="SUCCESS">Load succeeded</int> <int value="1" label="FAILED_OPEN">Failure to open snapshot file</int> <int value="2" label="FAILED_MAP">Failed to map snapshot</int> <int value="3" label="FAILED_VERIFY">Failed to verify snapshot</int> </enum> -<enum name="V8InitializerOpenV8FileResult" type="int"> +<enum name="V8InitializerOpenV8FileResult"> <int value="0" label="OPENED">Opened without issue</int> <int value="1" label="OPENED_RETRY">Opened after one or more retries</int> <int value="2" label="FAILED_IN_USE">Failed because file in use</int> <int value="3" label="FAILED_OTHER">Failed for other reason</int> </enum> -<enum name="VAJDADecoderFailure" type="int"> +<enum name="VAJDADecoderFailure"> <int value="0" label="VAAPI_ERROR"/> </enum> -<enum name="ValidateMenuItemSelectorType" type="int"> +<enum name="ValidateMenuItemSelectorType"> <int value="0" label="The menu items' associated action is an unknown selector."/> <int value="1" label="The menu item's associated action is -newProfile."/> @@ -37013,12 +37017,12 @@ label="The menu item's associated action is -switchToProfileFromDock."/> </enum> -<enum name="ValidationFailures" type="int"> +<enum name="ValidationFailures"> <int value="0" label="DBus"/> <int value="1" label="Load Key"/> </enum> -<enum name="VariationSeedSignature" type="int"> +<enum name="VariationSeedSignature"> <int value="0" label="Signature Missing"/> <int value="1" label="Signature Decode Failed"/> <int value="2" label="Invalid Signature"/> @@ -37026,7 +37030,7 @@ <int value="4" label="Valid Signature for Seed"/> </enum> -<enum name="VariationsFirstRunResult" type="int"> +<enum name="VariationsFirstRunResult"> <int value="0" label="Seed imported successfully"/> <int value="1" label="Seed import failed - no callback (Obsolete)"/> <int value="2" label="Seed import failed - no first run seed"/> @@ -37034,7 +37038,7 @@ <int value="4" label="Seed import failed - invalid response date string"/> </enum> -<enum name="VariationsFirstRunSeedFetchResult" type="int"> +<enum name="VariationsFirstRunSeedFetchResult"> <int value="-3" label="UnknownHostException fetching seed"/> <int value="-2" label="SocketTimeoutException fetching seed"/> <int value="-1" label="IOException fetching seed"/> @@ -37079,7 +37083,7 @@ <int value="505" label="505: HTTP Version Not Supported"/> </enum> -<enum name="VariationsHeadersURLValidationResult" type="int"> +<enum name="VariationsHeadersURLValidationResult"> <int value="0" label="Rejected: Invalid URL."/> <int value="1" label="Rejected: Not https. (Deprecated)"/> <int value="2" label="Rejected: Not Google domain."/> @@ -37088,7 +37092,7 @@ <int value="5" label="Rejected: Is a Google domain, but not https."/> </enum> -<enum name="VariationsPermanentConsistencyCountryResult" type="int"> +<enum name="VariationsPermanentConsistencyCountryResult"> <int value="0" label="Saved pref missing and no country code in seed"/> <int value="1" label="Saved pref missing and country code in seed"/> <int value="2" label="Saved pref invalid and no country code in seed"/> @@ -37113,7 +37117,7 @@ seed is different"/> </enum> -<enum name="VariationsResourceRequestsAllowedState" type="int"> +<enum name="VariationsResourceRequestsAllowedState"> <int value="0" label="Requests allowed"/> <int value="1" label="Requests not allowed (Obsolete 11/2013)"/> <int value="2" label="Notified that requests became allowed"/> @@ -37122,20 +37126,20 @@ <int value="5" label="Requests not allowed: disabled by command line"/> </enum> -<enum name="VariationsSeedDateChange" type="int"> +<enum name="VariationsSeedDateChange"> <int value="0" label="No previous date"/> <int value="1" label="New date older than old date"/> <int value="2" label="Same day"/> <int value="3" label="Day changed"/> </enum> -<enum name="VariationsSeedExpiry" type="int"> +<enum name="VariationsSeedExpiry"> <int value="0" label="Not Expired"/> <int value="1" label="Fetch Time Missing"/> <int value="2" label="Expired"/> </enum> -<enum name="VariationsSeedLoadResult" type="int"> +<enum name="VariationsSeedLoadResult"> <int value="0" label="Seed Loaded Successfully"/> <int value="1" label="Seed Empty"/> <int value="2" label="Seed Corrupt (Obsolete)"/> @@ -37145,7 +37149,7 @@ <int value="6" label="Seed Corrupt Gzip Data"/> </enum> -<enum name="VariationsSeedStoreResult" type="int"> +<enum name="VariationsSeedStoreResult"> <int value="0" label="Success"/> <int value="1" label="Failed - Empty Seed"/> <int value="2" label="Failed - Parse Error"/> @@ -37160,17 +37164,17 @@ <int value="11" label="Failed - Unsupported Seed Format"/> </enum> -<enum name="VaryType" type="int"> +<enum name="VaryType"> <int value="0" label="No Vary header present"/> <int value="1" label="Vary:User-Agent"/> <int value="2" label="Other"/> </enum> -<enum name="VAVDADecoderFailure" type="int"> +<enum name="VAVDADecoderFailure"> <int value="0" label="VAAPI_ERROR"/> </enum> -<enum name="VAVDAH264DecoderFailure" type="int"> +<enum name="VAVDAH264DecoderFailure"> <int value="0" label="FRAME_MBS_ONLY_FLAG_NOT_ONE"/> <int value="1" label="GAPS_IN_FRAME_NUM"/> <int value="2" label="MID_STREAM_RESOLUTION_CHANGE"/> @@ -37178,11 +37182,11 @@ <int value="4" label="VAAPI_ERROR"/> </enum> -<enum name="VAVEAEncoderFailure" type="int"> +<enum name="VAVEAEncoderFailure"> <int value="0" label="VAAPI_ERROR"/> </enum> -<enum name="VerifyWakeOnWiFiSettingsResult" type="int"> +<enum name="VerifyWakeOnWiFiSettingsResult"> <summary> The result of NIC wake on WiFi settings verification. Corresponds to VerifyWakeOnWiFiSettingsResult in shill/metrics.h @@ -37191,7 +37195,7 @@ <int value="1" label="Failure"/> </enum> -<enum name="VideoCaptureEvent" type="int"> +<enum name="VideoCaptureEvent"> <int value="0" label="Starting video capture"/> <int value="1" label="Stopping video capture normally"/> <int value="2" label="Stopping video capture due to error"/> @@ -37199,7 +37203,7 @@ <int value="4" label="Desktop/Tab capture stopped. No frames produced."/> </enum> -<enum name="VideoCodec" type="int"> +<enum name="VideoCodec"> <int value="0" label="kUnknownVideoCodec"/> <int value="1" label="kCodecH264"/> <int value="2" label="kCodecVC1"/> @@ -37212,7 +37216,7 @@ <int value="9" label="kCodecDolbyVision"/> </enum> -<enum name="VideoCodecProfile" type="int"> +<enum name="VideoCodecProfile"> <int value="0" label="H.264 Baseline"/> <int value="1" label="H.264 Main"/> <int value="2" label="H.264 Extended"/> @@ -37238,7 +37242,7 @@ <int value="22" label="DolbyVision profile7"/> </enum> -<enum name="VideoDecodeAcceleratorError" type="int"> +<enum name="VideoDecodeAcceleratorError"> <int value="1" label="Illegal state"> An operation was attempted during an incompatible decoder state. </int> @@ -37253,7 +37257,7 @@ </int> </enum> -<enum name="VideoFormat" type="int"> +<enum name="VideoFormat"> <obsolete> Deprecated as of 05/2015. Substituted by VideoFramePixelFormat. </obsolete> @@ -37269,14 +37273,14 @@ <int value="9" label="NATIVE_TEXTURE"/> </enum> -<enum name="VideoFrameColorSpace" type="int"> +<enum name="VideoFrameColorSpace"> <int value="0" label="Unspecified, usually Rec 601"/> <int value="1" label="Jpeg"/> <int value="2" label="HD Rec 709"/> <int value="3" label="SD Rec 601"/> </enum> -<enum name="VideoFrameColorSpaceUMA" type="int"> +<enum name="VideoFrameColorSpaceUMA"> <int value="0" label="Unknown"/> <int value="1" label="UnknownRGB"/> <int value="2" label="UnknownHDR"/> @@ -37288,7 +37292,7 @@ <int value="8" label="scRGB"/> </enum> -<enum name="VideoFramePixelFormat" type="int"> +<enum name="VideoFramePixelFormat"> <obsolete> Deprecated as of 08/2015. Substituted by VideoPixelFormatUnion. </obsolete> @@ -37304,19 +37308,19 @@ <int value="9" label="UYVY"/> </enum> -<enum name="VideoFullscreenOrientationLockMetadataAvailability" type="int"> +<enum name="VideoFullscreenOrientationLockMetadataAvailability"> <int value="0" label="Available"/> <int value="1" label="Missing"/> <int value="2" label="Received (after Missing)"/> </enum> -<enum name="VideoFullscreenOrientationLockResult" type="int"> +<enum name="VideoFullscreenOrientationLockResult"> <int value="0" label="Already locked, no attempt"/> <int value="1" label="Portrait"/> <int value="2" label="Landscape"/> </enum> -<enum name="VideoPersistenceAttemptResult" type="int"> +<enum name="VideoPersistenceAttemptResult"> <int value="0" label="Success"/> <int value="1" label="No system support"/> <int value="2" label="No feature"/> @@ -37328,12 +37332,12 @@ <int value="8" label="No video"/> </enum> -<enum name="VideoPersistenceControlsType" type="int"> +<enum name="VideoPersistenceControlsType"> <int value="0" label="Native controls"/> <int value="1" label="Custom controls"/> </enum> -<enum name="VideoPersistenceEndReason" type="int"> +<enum name="VideoPersistenceEndReason"> <int value="0" label="Resume"/> <int value="1" label="Navigation"/> <int value="2" label="Close"/> @@ -37343,7 +37347,7 @@ <int value="6" label="Left fullscreen"/> </enum> -<enum name="VideoPixelFormat" type="int"> +<enum name="VideoPixelFormat"> <obsolete> Deprecated as of 05/2015. Substituted by VideoFormat. </obsolete> @@ -37361,7 +37365,7 @@ <int value="11" label="YV12HD"/> </enum> -<enum name="VideoPixelFormatUnion" type="int"> +<enum name="VideoPixelFormatUnion"> <int value="0" label="UNKNOWN"/> <int value="1" label="I420"/> <int value="2" label="YV12"/> @@ -37391,7 +37395,7 @@ <int value="26" label="Y16"/> </enum> -<enum name="VideoPlayerCastAPIExtensionStatus" type="int"> +<enum name="VideoPlayerCastAPIExtensionStatus"> <int value="0" label="Skipped (Cast extension is unavailable)"/> <int value="1" label="Installation failed"/> <int value="2" label="Load failed"/> @@ -37399,19 +37403,19 @@ <int value="4" label="Loaded successfully (already installed)"/> </enum> -<enum name="VideoPlayerPlayType" type="int"> +<enum name="VideoPlayerPlayType"> <int value="0" label="Local playback"/> <int value="1" label="Play on cast device"/> </enum> -<enum name="VideoRotation" type="int"> +<enum name="VideoRotation"> <int value="0" label="VIDEO_ROTATION_0"/> <int value="1" label="VIDEO_ROTATION_90"/> <int value="2" label="VIDEO_ROTATION_180"/> <int value="3" label="VIDEO_ROTATION_270"/> </enum> -<enum name="ViewFileType" type="int"> +<enum name="ViewFileType"> <int value="0" label="other"/> <int value="1" label=".3ga"/> <int value="2" label=".3gp"/> @@ -37474,18 +37478,18 @@ <int value="59" label=".zip"/> </enum> -<enum name="VisibleTab" type="int"> +<enum name="VisibleTab"> <int value="0" label="Custom Tab"/> <int value="1" label="Chrome Tab"/> </enum> -<enum name="VPNDriver" type="int"> +<enum name="VPNDriver"> <int value="0" label="OpenVPN"/> <int value="1" label="L2TP/IPSec"/> <int value="2" label="Third Party"/> </enum> -<enum name="VPNRemoteAuthenticationType" type="int"> +<enum name="VPNRemoteAuthenticationType"> <int value="0" label="OpenVPN Default"/> <int value="1" label="OpenVPN Certificate"/> <int value="2" label="L2TP/IPSec Default"/> @@ -37493,7 +37497,7 @@ <int value="4" label="L2TP/IPSec PSK"/> </enum> -<enum name="VPNUserAuthenticationType" type="int"> +<enum name="VPNUserAuthenticationType"> <int value="0" label="OpenVPN None"/> <int value="1" label="OpenVPN Certificate"/> <int value="2" label="OpenVPN Username/Password"/> @@ -37503,27 +37507,27 @@ <int value="6" label="L2TP/IPSec Username/Password"/> </enum> -<enum name="VRUnsupportedMode" type="int"> +<enum name="VRUnsupportedMode"> <int value="0" label="Unhandled code point in URL"/> <int value="1" label="Could not elide URL"/> <int value="2" label="Unhandled PageInfo"/> <int value="3" label="URL contained strong RTL chars"/> </enum> -<enum name="VRViewerType" type="int"> +<enum name="VRViewerType"> <int value="0" label="UNKNOWN_TYPE"/> <int value="1" label="CARDBOARD"/> <int value="2" label="DAYDREAM"/> </enum> -<enum name="VTVDAInitializationFailureType" type="int"> +<enum name="VTVDAInitializationFailureType"> <int value="0" label="Successfully Initialized"/> <int value="1" label="Framework Load Error"/> <int value="2" label="Hardware Session Error"/> <int value="3" label="Software Session Error"/> </enum> -<enum name="VTVDASessionFailureType" type="int"> +<enum name="VTVDASessionFailureType"> <int value="0" label="Successfully Initialized"/> <int value="1" label="Platform Error"/> <int value="2" label="Invalid Stream"/> @@ -37532,14 +37536,14 @@ <int value="5" label="Unsupported Stream"/> </enum> -<enum name="WaitForVBlankErrorCode" type="int"> +<enum name="WaitForVBlankErrorCode"> <int value="0" label="Success"/> <int value="1" label="Failed to get monitor info"/> <int value="2" label="Failed to open adapter"/> <int value="3" label="Failed to wait for VBlank event"/> </enum> -<enum name="WakeOnWiFiFeaturesEnabledState" type="int"> +<enum name="WakeOnWiFiFeaturesEnabledState"> <summary> The wake on WiFi features enabled in shill, which come from WakeOnWiFiFeaturesEnabledState in shill/metrics.h @@ -37550,7 +37554,7 @@ <int value="3" label="Packet and DarkConnect"/> </enum> -<enum name="WakeOnWiFiThrottled" type="int"> +<enum name="WakeOnWiFiThrottled"> <summary> Whether or not wake on WiFi was disabled during suspend because of excessive dark resume wakes. Corresponds to WakeOnWiFiThrottled in shill/metrics.h @@ -37563,12 +37567,12 @@ wakes"/> </enum> -<enum name="WakeReasonReceivedBeforeOnDarkResume" type="int"> +<enum name="WakeReasonReceivedBeforeOnDarkResume"> <int value="0" label="Wake reason not received before OnDarkResume"/> <int value="1" label="Wake reason received before OnDarkResume"/> </enum> -<enum name="WalletApiCall" type="int"> +<enum name="WalletApiCall"> <int value="0" label="Unknown API call"/> <int value="1" label="Accept Legal Documents"/> <int value="2" label="Authenticate Instrument"/> @@ -37577,7 +37581,7 @@ <int value="5" label="Save to Wallet"/> </enum> -<enum name="WalletErrors" type="int"> +<enum name="WalletErrors"> <int value="0" label="Baseline: Issued request"/> <int value="1" label="Fatal error (deprecated)"/> <int value="2" label="Malformed response"/> @@ -37594,7 +37598,7 @@ <int value="13" label="Unverified know your customer status"/> </enum> -<enum name="WalletRequiredActions" type="int"> +<enum name="WalletRequiredActions"> <int value="0" label="Baseline: Issued request"/> <int value="1" label="Unknown"/> <int value="2" label="GAIA auth"/> @@ -37609,19 +37613,19 @@ <int value="11" label="Require phone number"/> </enum> -<enum name="WallpaperApps" type="int"> +<enum name="WallpaperApps"> <int value="0" label="Chrome OS Wallpaper Picker App"/> <int value="1" label="Android Wallpapers App"/> </enum> -<enum name="WallpaperLayout" type="int"> +<enum name="WallpaperLayout"> <int value="0" label="Center"/> <int value="1" label="Center Cropped"/> <int value="2" label="Stretch"/> <int value="3" label="Tile"/> </enum> -<enum name="WallpaperType" type="int"> +<enum name="WallpaperType"> <int value="0" label="Daily"/> <int value="1" label="Customized"/> <int value="2" label="Default"/> @@ -37632,7 +37636,7 @@ <int value="7" label="Device policy"/> </enum> -<enum name="WarmupStateOnLaunch" type="int"> +<enum name="WarmupStateOnLaunch"> <int value="0" label="No Session, No Warmup"/> <int value="1" label="No Session, Warmup"/> <int value="2" label="Session, No Warmup, Warmup called from another UID"/> @@ -37640,7 +37644,7 @@ <int value="4" label="Session, Warmup"/> </enum> -<enum name="WebApkGooglePlayInstallResult" type="int"> +<enum name="WebApkGooglePlayInstallResult"> <int value="0" label="Success"/> <int value="1" label="Install delegate unavailable"/> <int value="2" label="Failed to connect to Google Play Install Service"/> @@ -37659,7 +37663,7 @@ <int value="14" label="Request to Play install API failed - Resolve Error"/> </enum> -<enum name="WebApkGooglePlayInstallState" type="int"> +<enum name="WebApkGooglePlayInstallState"> <int value="0" label="Play installation supported."/> <int value="1" label="Play installation disabled for other reason."/> <int value="2" label="Google Play Services unavailable."/> @@ -37668,7 +37672,7 @@ <int value="4" label="Play installation disabled by Play."/> </enum> -<enum name="WebApkInstallEvent" type="int"> +<enum name="WebApkInstallEvent"> <int value="0" label="Infobar is ignored"/> <int value="1" label="Infobar is dismissed before installation"/> <int value="2" label="Infobar is dismissed during installation"/> @@ -37676,48 +37680,48 @@ <int value="4" label="Failed"/> </enum> -<enum name="WebApkInstallInfoBarShown" type="int"> +<enum name="WebApkInstallInfoBarShown"> <int value="0" label="WebApk infobar shown from the app banner"/> <int value="1" label="WebApk infobar shown from the add to homescreen menu"/> </enum> -<enum name="WebApkInstallSource" type="int"> +<enum name="WebApkInstallSource"> <int value="0" label="Installation started from the app banner"/> <int value="1" label="Installation started from the add to homescreen menu"/> </enum> -<enum name="WebApkOpenResult" type="int"> +<enum name="WebApkOpenResult"> <int value="0" label="Open an installed WebAPK successfully"/> <int value="1" label="Launch intent for WebAPK is null"/> <int value="2" label="Activity for WebAPK not found."/> </enum> -<enum name="WebApkUpdateRequestQueued" type="int"> +<enum name="WebApkUpdateRequestQueued"> <int value="0" label="Queued for the first time"/> <int value="1" label="Queued for the second time"/> <int value="2" label="Queued for the third time"/> </enum> -<enum name="WebApkUpdateRequestSent" type="int"> +<enum name="WebApkUpdateRequestSent"> <int value="0" label="Sent immediately after an update check"/> <int value="1" label="Sent when WebAPK is moved to background"/> <int value="2" label="Sent by forcing an update"/> </enum> -<enum name="WebApkUserAction" type="int"> +<enum name="WebApkUserAction"> <int value="0" label="Open a previously installed WebAPK"/> <int value="1" label="Dismiss to open a previously installed WebAPK"/> <int value="2" label="Open a newly installed WebAPK"/> <int value="3" label="Dismiss to open a newly installed WebAPK"/> </enum> -<enum name="WebAudioAutoplayStatus" type="int"> +<enum name="WebAudioAutoplayStatus"> <int value="0" label="The AudioContext failed to autoplay"/> <int value="1" label="Failed to autoplay but start() called on user gesture"/> <int value="2" label="The AudioContext successfully autoplayed"/> </enum> -<enum name="WebBluetoothConnectGATTOutcome" type="int"> +<enum name="WebBluetoothConnectGATTOutcome"> <int value="0" label="Success"/> <int value="1" label="Device no longer in range"/> <int value="2" label="Unknown Error"/> @@ -37730,7 +37734,7 @@ <int value="9" label="Unsupported Device"/> </enum> -<enum name="WebBluetoothFunction" type="int"> +<enum name="WebBluetoothFunction"> <int value="0" label="requestDevice()"/> <int value="1" label="RemoteGATTServer.connect()"/> <int value="2" label="RemoteGATTServer.getPrimaryService()"/> @@ -37748,7 +37752,7 @@ <int value="14" label="RemoteGATTCharacteristic.getDescriptors()"/> </enum> -<enum name="WebBluetoothGATTOperationOutcome" type="int"> +<enum name="WebBluetoothGATTOperationOutcome"> <int value="0" label="Success"/> <int value="1" label="No Device"/> <int value="2" label="No Service"/> @@ -37765,7 +37769,7 @@ <int value="13" label="Blocklisted"/> </enum> -<enum name="WebBluetoothGetCharacteristicOutcome" type="int"> +<enum name="WebBluetoothGetCharacteristicOutcome"> <int value="0" label="Success"/> <int value="1" label="No device"/> <int value="2" label="No service"/> @@ -37774,7 +37778,7 @@ <int value="5" label="No characteristics"/> </enum> -<enum name="WebBluetoothGetDescriptorOutcome" type="int"> +<enum name="WebBluetoothGetDescriptorOutcome"> <int value="0" label="Success"/> <int value="1" label="No device"/> <int value="2" label="No service"/> @@ -37784,7 +37788,7 @@ <int value="6" label="No descriptors"/> </enum> -<enum name="WebBluetoothGetPrimaryServiceOutcome" type="int"> +<enum name="WebBluetoothGetPrimaryServiceOutcome"> <int value="0" label="Success"/> <int value="1" label="Device no longer in range."/> <int value="2" label="Not found"/> @@ -37792,7 +37796,7 @@ <int value="4" label="Device disconnected"/> </enum> -<enum name="WebBluetoothRequestDeviceOutcome" type="int"> +<enum name="WebBluetoothRequestDeviceOutcome"> <int value="0" label="Success"/> <int value="1" label="No Bluetooth adapter"/> <int value="2" label="No RenderFrameHost for message source"/> @@ -37820,7 +37824,7 @@ <int value="19" label="Chooser re-scan link pressed."/> </enum> -<enum name="WebBluetoothRSSISignalStrengthLevel" type="int"> +<enum name="WebBluetoothRSSISignalStrengthLevel"> <int value="0" label="<= minimum RSSI; displayed as level 0"/> <int value="1" label="RSSI displayed as level 0"/> <int value="2" label="RSSI displayed as level 1"/> @@ -37830,47 +37834,47 @@ <int value="6" label=">= maximium RSSI; displayed as level 4"/> </enum> -<enum name="WebCertVerifyAgreement" type="int"> +<enum name="WebCertVerifyAgreement"> <int value="0" label="Accepted by both iOS and NSS."/> <int value="1" label="Rejected by both iOS and NSS."/> <int value="2" label="Accepted only by iOS (rejected by NSS)."/> <int value="3" label="Accepted only by NSS (rejected by iOS)."/> </enum> -<enum name="WebContentsState" type="int"> +<enum name="WebContentsState"> <int value="0" label="No WebContents"/> <int value="1" label="Prerendered WebContents"/> <int value="2" label="Spare WebContents"/> </enum> -<enum name="WebFontCacheHit" type="int"> +<enum name="WebFontCacheHit"> <int value="0" label="Miss"/> <int value="1" label="Hit disk cache"/> <int value="2" label="Served from data URL"/> <int value="3" label="Hit memory cache"/> </enum> -<enum name="WebFontDiskCacheHit" type="int"> +<enum name="WebFontDiskCacheHit"> <int value="0" label="Not in the cache"/> <int value="1" label="In the cache"/> <int value="2" label="Previously in the cache"/> </enum> -<enum name="WebFontInterventionResult" type="int"> +<enum name="WebFontInterventionResult"> <int value="0" label="Wasn't triggered, and does not time out"/> <int value="1" label="Wasn't triggered, but time out"/> <int value="2" label="Was triggered, but would not time out"/> <int value="3" label="Was triggered, and would time out"/> </enum> -<enum name="WebFontLoadLimitState" type="int"> +<enum name="WebFontLoadLimitState"> <int value="0" label="Load not started"/> <int value="1" label="Under limit"/> <int value="2" label="Short limit exceeded"/> <int value="3" label="Long limit exceeded"/> </enum> -<enum name="WebFontPackageFormat" type="int"> +<enum name="WebFontPackageFormat"> <int value="0" label="Unknown / Decode error"/> <int value="1" label="SFNT"/> <int value="2" label="WOFF"/> @@ -37878,19 +37882,19 @@ <int value="4" label="SVG"/> </enum> -<enum name="WebFontUsageType" type="int"> +<enum name="WebFontUsageType"> <int value="0" label="Styled, and used"/> <int value="1" label="Styled, but not used"/> <int value="2" label="Not styled, but used"/> </enum> -<enum name="WebHistoryStatus" type="int"> +<enum name="WebHistoryStatus"> <int value="0" label="WEB_HISTORY_QUERY_FAILED">Failed</int> <int value="1" label="WEB_HISTORY_QUERY_SUCCEEDED">Succeeded</int> <int value="2" label="WEB_HISTORY_QUERY_TIMED_OUT">Timed out</int> </enum> -<enum name="WebRTCAecDelayEstimateReliability" type="int"> +<enum name="WebRTCAecDelayEstimateReliability"> <int value="0" label="None."/> <int value="1" label="Poor."/> <int value="2" label="Medium."/> @@ -37898,7 +37902,7 @@ <int value="4" label="Excellent."/> </enum> -<enum name="WebRtcAudioCodecs" type="int"> +<enum name="WebRtcAudioCodecs"> <int value="0" label="Unknown"/> <int value="1" label="Opus"/> <int value="2" label="iSAC"/> @@ -37908,14 +37912,14 @@ <int value="6" label="iLBC"/> </enum> -<enum name="WebRtcBweType" type="int"> +<enum name="WebRtcBweType"> <int value="0" label="Receiver, no extension"/> <int value="1" label="Receiver, transmission offset"/> <int value="2" label="Receiver, absolute send time"/> <int value="3" label="Sender, transport sequence number"/> </enum> -<enum name="WebRTCEventFrequency" type="int"> +<enum name="WebRTCEventFrequency"> <int value="0" label="None."/> <int value="1" label="Few."/> <int value="2" label="Several."/> @@ -37923,34 +37927,34 @@ <int value="4" label="Constant."/> </enum> -<enum name="WebRtcH264DecoderImplEvent" type="int"> +<enum name="WebRtcH264DecoderImplEvent"> <int value="0" label="Init"/> <int value="1" label="Error"/> </enum> -<enum name="WebRtcH264EncoderImplEvent" type="int"> +<enum name="WebRtcH264EncoderImplEvent"> <int value="0" label="Init"/> <int value="1" label="Error"/> </enum> -<enum name="WebRtcVideoCodecs" type="int"> +<enum name="WebRtcVideoCodecs"> <int value="0" label="Unknown"/> <int value="1" label="VP8"/> <int value="2" label="VP9"/> <int value="3" label="H264"/> </enum> -<enum name="WebShareMethod" type="int"> +<enum name="WebShareMethod"> <int value="0" label="Share"/> </enum> -<enum name="WebShareOutcome" type="int"> +<enum name="WebShareOutcome"> <int value="0" label="Success"/> <int value="1" label="UnknownFailure"/> <int value="2" label="Canceled"/> </enum> -<enum name="WebsiteSettingsAction" type="int"> +<enum name="WebsiteSettingsAction"> <int value="0" label="Opened"/> <int value="1" label="(Deprecated) Selected Permissions tab"/> <int value="2" label="(Deprecated) Selected Connection tab"/> @@ -37964,43 +37968,43 @@ <int value="10" label="Security details opened"/> </enum> -<enum name="WebSocketHandshakeResult" type="int"> +<enum name="WebSocketHandshakeResult"> <int value="0" label="Incomplete"/> <int value="1" label="Normal"/> <int value="2" label="Failed"/> <int value="3" label="Connected"/> </enum> -<enum name="WebSocketNewHandshakeResult" type="int"> +<enum name="WebSocketNewHandshakeResult"> <int value="0" label="INCOMPLETE">Incomplete</int> <int value="1" label="CONNECTED">Connected</int> <int value="2" label="FAILED">Failed</int> </enum> -<enum name="WebSocketNewPerMessageDeflateContextTakeoverMode" type="int"> +<enum name="WebSocketNewPerMessageDeflateContextTakeoverMode"> <int value="0" label="Do not take over"/> <int value="1" label="Take over"/> </enum> -<enum name="WebSocketPerMessageDeflateContextTakeOverMode" type="int"> +<enum name="WebSocketPerMessageDeflateContextTakeOverMode"> <int value="0" label="Do not take over"/> <int value="1" label="Take over"/> </enum> -<enum name="WebSocketReceiveType" type="int"> +<enum name="WebSocketReceiveType"> <int value="0" label="String"/> <int value="1" label="ArrayBuffer"/> <int value="2" label="Blob"/> </enum> -<enum name="WebSocketSendType" type="int"> +<enum name="WebSocketSendType"> <int value="0" label="String"/> <int value="1" label="ArrayBuffer"/> <int value="2" label="ArrayBufferView"/> <int value="3" label="Blob"/> </enum> -<enum name="WebUIUrlHashes" type="int"> +<enum name="WebUIUrlHashes"> <int value="-2103246641" label="chrome://signin-internals/"/> <int value="-2034706497" label="chrome://net-internals/"/> <int value="-1911971715" label="chrome://history/"/> @@ -38117,26 +38121,26 @@ <int value="3251925547" label="chrome://offline-internals/"/> </enum> -<enum name="WebUsbChooserClosed" type="int"> +<enum name="WebUsbChooserClosed"> <int value="0" label="User cancelled"/> <int value="1" label="User cancelled, no devices available"/> <int value="2" label="Permission granted"/> <int value="3" label="Ephemeral permission granted"/> </enum> -<enum name="WebUsbNotificationClosed" type="int"> +<enum name="WebUsbNotificationClosed"> <int value="0" label="Closed by system"/> <int value="1" label="Closed by user"/> <int value="2" label="Clicked"/> <int value="3" label="Manual navigation to the landing page"/> </enum> -<enum name="WebUsbPermissionRevoked" type="int"> +<enum name="WebUsbPermissionRevoked"> <int value="0" label="Revoked permission"/> <int value="1" label="Revoked ephemeral permission"/> </enum> -<enum name="WelcomeSignInPromptOutcome" type="int"> +<enum name="WelcomeSignInPromptOutcome"> <int value="0" label="User navigated away from page"/> <int value="1" label="User clicked the No Thanks button"/> <int value="2" label="User completed sign-in flow"/> @@ -38144,26 +38148,26 @@ <int value="4" label="User attempted sign-in flow, then clicked No Thanks"/> </enum> -<enum name="WhitelistedDownloadType" type="int"> +<enum name="WhitelistedDownloadType"> <int value="0" label="Does not match any whitelists"/> <int value="1" label="URL whitelist"/> <int value="2" label="Signature whitelist"/> </enum> -<enum name="WiFiApMode" type="int"> +<enum name="WiFiApMode"> <int value="0" label="Unknown"/> <int value="1" label="Managed"/> <int value="2" label="AdHoc"/> </enum> -<enum name="WiFiConnectionStatusAfterWake" type="int"> +<enum name="WiFiConnectionStatusAfterWake"> <int value="0" label="Connected (Wake On WiFi enabled)"/> <int value="1" label="Not connected (Wake On WiFi enabled)"/> <int value="2" label="Connected (Wake On WiFi disabled)"/> <int value="3" label="Not connected (Wake On WiFi disabled)"/> </enum> -<enum name="WiFiReasonCode" type="int"> +<enum name="WiFiReasonCode"> <int value="0" label="kReasonReserved0"/> <int value="1" label="kReasonCodeUnspecified"/> <int value="2" label="kReasonCodePreviousAuthenticationInvalid"/> @@ -38207,7 +38211,7 @@ <int value="45" label="kReasonCodeCipherSuiteNotSupported"/> </enum> -<enum name="WiFiScanResult" type="int"> +<enum name="WiFiScanResult"> <int value="0" label="ProgressiveScan connected"/> <int value="1" label="ProgressiveScan error then FullScan didn't connect"/> <int value="2" label="ProgressiveScan error then FullScan connected"/> @@ -38220,21 +38224,21 @@ <int value="7" label="Internal error"/> </enum> -<enum name="WiFiStatusType" type="int"> +<enum name="WiFiStatusType"> <int value="0" label="kStatusCodeTypeByAp"/> <int value="1" label="kStatusCodeTypeByClient"/> <int value="2" label="kStatusCodeTypeByUser"/> <int value="3" label="kStatusCodeTypeConsideredDead"/> </enum> -<enum name="Win8PageLoadType" type="int"> +<enum name="Win8PageLoadType"> <int value="0" label="Metro"/> <int value="1" label="Desktop"/> <int value="2" label="Metro Aura"/> <int value="3" label="Desktop Aura"/> </enum> -<enum name="WindowOpenDisposition" type="int"> +<enum name="WindowOpenDisposition"> <int value="0" label="Unknown"/> <int value="1" label="Current Tab"/> <int value="2" label="Singleton Tab"/> @@ -38247,7 +38251,7 @@ <int value="9" label="Ignore Action"/> </enum> -<enum name="WindowsExitCode" type="int"> +<enum name="WindowsExitCode"> <int value="-2147483645" label="0x80000003 - STATUS_BREAKPOINT"/> <int value="-1073741819" label="0xC0000005 - STATUS_ACCESS_VIOLATION"/> <int value="-1073740972" label="0xC0000354 - STATUS_DEBUGGER_INACTIVE"/> @@ -38293,7 +38297,7 @@ <int value="1073807364" label="0x40010004 - DBG_TERMINATE_PROCESS"/> </enum> -<enum name="WindowsVersion" type="int"> +<enum name="WindowsVersion"> <int value="0" label="Pre-XP"/> <int value="1" label="XP"/> <int value="2" label="2003 Server"/> @@ -38307,14 +38311,14 @@ <int value="10" label="Windows 10 RS2"/> </enum> -<enum name="WindowType" type="int"> +<enum name="WindowType"> <int value="0" label="Other"/> <int value="1" label="Browser"/> <int value="2" label="Hosted App"/> <int value="3" label="Packaged App"/> </enum> -<enum name="WinGetLastError" type="int"> +<enum name="WinGetLastError"> <int value="0" label="SUCCESS"/> <int value="1" label="INVALID_FUNCTION"/> <int value="2" label="FILE_NOT_FOUND"/> @@ -38833,20 +38837,20 @@ <int value="999" label="SWAPERROR"/> </enum> -<enum name="WinJumplistCategory" type="int"> +<enum name="WinJumplistCategory"> <int value="0" label="Recently Closed"/> <int value="1" label="Most Visited"/> <int value="2" label="People"/> </enum> -<enum name="WorkerThreadExitCode" type="int"> +<enum name="WorkerThreadExitCode"> <int value="0" label="NotTerminated"/> <int value="1" label="GracefullyTerminated"/> <int value="2" label="SyncForciblyTerminated"/> <int value="3" label="AsyncForciblyTerminated"/> </enum> -<enum name="WrenchMenuAction" type="int"> +<enum name="WrenchMenuAction"> <int value="0" label="New tab"/> <int value="1" label="New window"/> <int value="2" label="New incognito window"/> @@ -38895,7 +38899,7 @@ <int value="45" label="Cast"/> </enum> -<enum name="XFrameOptions" type="int"> +<enum name="XFrameOptions"> <int value="0" label="NONE"> A frame is loaded without any X-Frame-Options header. </int> @@ -38925,28 +38929,28 @@ </int> </enum> -<enum name="XMLHttpRequestHeaderValueCategoryInRFC7230" type="int"> +<enum name="XMLHttpRequestHeaderValueCategoryInRFC7230"> <int value="0" label="Header Value Invalid"/> <int value="1" label="Header Value Affected By Normalization"/> <int value="2" label="Header Value Valid"/> </enum> -<enum name="XMLHttpRequestSendArrayBufferOrView" type="int"> +<enum name="XMLHttpRequestSendArrayBufferOrView"> <int value="0" label="XMLHttpRequestSendArrayBuffer"/> <int value="1" label="XMLHttpRequestSendArrayBufferView"/> </enum> -<enum name="XPCConnectionEvent" type="int"> +<enum name="XPCConnectionEvent"> <int value="0" label="Interrupted"/> <int value="1" label="Invalidated"/> </enum> -<enum name="YoungGenerationHandling" type="int"> +<enum name="YoungGenerationHandling"> <int value="0" label="Regular Scavenge"/> <int value="1" label="Scavenge using fast promotion mode"/> </enum> -<enum name="YouTubeRewriteStatus" type="int"> +<enum name="YouTubeRewriteStatus"> <int value="0" label="Success">Embed was properly rewritten.</int> <int value="1" label="Success, params were rewritten"> Embed was rewritten but the params had to be fixed. @@ -38959,7 +38963,7 @@ </int> </enum> -<enum name="ZeroSuggestEligibleOnFocus" type="int"> +<enum name="ZeroSuggestEligibleOnFocus"> <int value="0" label="Eligible"> URL can be currently sent to the suggest server. </int>
diff --git a/tools/metrics/histograms/extract_histograms.py b/tools/metrics/histograms/extract_histograms.py index c36334a..879a749 100644 --- a/tools/metrics/histograms/extract_histograms.py +++ b/tools/metrics/histograms/extract_histograms.py
@@ -184,11 +184,6 @@ last_name = None for enum in tree.getElementsByTagName('enum'): - if enum.getAttribute('type') != 'int': - logging.error('Unknown enum type %s', enum.getAttribute('type')) - have_errors = True - continue - name = enum.getAttribute('name') if last_name is not None and name.lower() < last_name.lower(): logging.error('Enums %s and %s are not in alphabetical order',
diff --git a/tools/metrics/histograms/print_style.py b/tools/metrics/histograms/print_style.py index 4e5efa1..77b9f54c 100644 --- a/tools/metrics/histograms/print_style.py +++ b/tools/metrics/histograms/print_style.py
@@ -17,7 +17,7 @@ ATTRIBUTE_ORDER = { 'affected-histogram': ['name'], 'details': [], - 'enum': ['name', 'type'], + 'enum': ['name'], 'enums': [], 'histogram': ['base', 'name', 'enum', 'units'], 'histogram-configuration': ['logsource'],
diff --git a/tools/perf/benchmarks/blob_storage.py b/tools/perf/benchmarks/blob_storage.py index 3fa2c7a7..5df337cb 100644 --- a/tools/perf/benchmarks/blob_storage.py +++ b/tools/perf/benchmarks/blob_storage.py
@@ -46,3 +46,6 @@ 'blob-reads' not in value.name): return False return value.values != None + + def GetExpectations(self): + return page_sets.BlobWorkshopStoryExpectations()
diff --git a/tools/perf/benchmarks/dummy_benchmark.py b/tools/perf/benchmarks/dummy_benchmark.py index 2d1e972..be2fae3 100644 --- a/tools/perf/benchmarks/dummy_benchmark.py +++ b/tools/perf/benchmarks/dummy_benchmark.py
@@ -18,7 +18,6 @@ from page_sets import dummy_story_set - class _DummyTest(legacy_page_test.LegacyPageTest): def __init__(self, avg, std): @@ -51,6 +50,9 @@ def Name(cls): return 'dummy_benchmark.stable_benchmark_1' + def GetExpectations(self): + return dummy_story_set.DummyStoryExpectations() + @benchmark.Owner(emails=['nednguyen@google.com']) class DummyBenchmarkTwo(_DummyBenchmark): @@ -62,3 +64,6 @@ @classmethod def Name(cls): return 'dummy_benchmark.noisy_benchmark_1' + + def GetExpectations(self): + return dummy_story_set.DummyStoryExpectations()
diff --git a/tools/perf/contrib/dromaeo_extras/dromaeo_extras.py b/tools/perf/contrib/dromaeo_extras/dromaeo_extras.py index a470075..fe6d68b 100644 --- a/tools/perf/contrib/dromaeo_extras/dromaeo_extras.py +++ b/tools/perf/contrib/dromaeo_extras/dromaeo_extras.py
@@ -3,6 +3,7 @@ # found in the LICENSE file. from telemetry import benchmark +from telemetry import story from benchmarks import dromaeo @@ -28,6 +29,12 @@ def Name(cls): return 'dromaeo.jslibattrjquery' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -45,6 +52,12 @@ def Name(cls): return 'dromaeo.jslibattrprototype' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -62,6 +75,12 @@ def Name(cls): return 'dromaeo.jslibeventjquery' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -79,6 +98,12 @@ def Name(cls): return 'dromaeo.jslibeventprototype' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + # win-ref: http://crbug.com/598705 # android: http://crbug.com/503138 @@ -99,6 +124,12 @@ def Name(cls): return 'dromaeo.jslibmodifyjquery' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -116,6 +147,12 @@ def Name(cls): return 'dromaeo.jslibmodifyprototype' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -133,6 +170,12 @@ def Name(cls): return 'dromaeo.jslibstylejquery' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -150,6 +193,12 @@ def Name(cls): return 'dromaeo.jslibstyleprototype' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -168,6 +217,12 @@ def Name(cls): return 'dromaeo.jslibtraversejquery' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + @benchmark.Owner(emails=['yukishiino@chromium.org', 'bashi@chromium.org', @@ -184,6 +239,12 @@ def Name(cls): return 'dromaeo.jslibtraverseprototype' + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations() + class DromaeoCSSQueryJquery(_BaseDromaeoBenchmark): """Dromaeo CSS Query jquery JavaScript benchmark. @@ -196,3 +257,9 @@ @classmethod def Name(cls): return 'dromaeo.cssqueryjquery' + + def GetExpectations(self): + class StoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # Nothing disabled. + return StoryExpectations()
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 2f85b3d..85b0e04e 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -128,7 +128,7 @@ { 'os': 'Android', 'android_devices': '1', - 'pool': 'Chrome-perf', + 'pool': 'Chrome-perf-fyi', 'device_ids': [ 'build243-m4--device1', 'build243-m4--device2', 'build243-m4--device3', 'build243-m4--device4',
diff --git a/tools/perf/page_sets/blob_workshop.py b/tools/perf/page_sets/blob_workshop.py index 049983f..7e38987 100644 --- a/tools/perf/page_sets/blob_workshop.py +++ b/tools/perf/page_sets/blob_workshop.py
@@ -85,8 +85,8 @@ self.AddStory( BlobMassCreate('10MBx30', [10 * 1024 * 1024] * 30, self)) # http://crbug.com/510815 - #self.AddStory( - # BlobMassCreate('80MBx5', [80 * 1024 * 1024] * 5, self)) + self.AddStory( + BlobMassCreate('80MBx5', [80 * 1024 * 1024] * 5, self)) self.AddStory(BlobCreateThenRead('2Bx200', [2] * 200, self)) self.AddStory(BlobCreateThenRead('1KBx200', [1024] * 200, self)) @@ -97,3 +97,9 @@ BlobCreateThenRead('10MBx30', [10 * 1024 * 1024] * 30, self)) self.AddStory( BlobCreateThenRead('80MBx5', [80 * 1024 * 1024] * 5, self)) + + +class BlobWorkshopStoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + self.DisableStory( + 'blob-mass-create-80MBx5', [story.expectations.ALL], 'crbug.com/510815')
diff --git a/tools/perf/page_sets/dummy_story_set.py b/tools/perf/page_sets/dummy_story_set.py index 884b00dd..37a3a3f6 100644 --- a/tools/perf/page_sets/dummy_story_set.py +++ b/tools/perf/page_sets/dummy_story_set.py
@@ -22,3 +22,8 @@ def __init__(self): super(DummyStorySet, self).__init__() self.AddStory(DummyPage(self)) + + +class DummyStoryExpectations(story.expectations.StoryExpectations): + def SetExpectations(self): + pass # No stories disabled.
diff --git a/ui/base/webui/jstemplate_builder.cc b/ui/base/webui/jstemplate_builder.cc index 16a338a..9a46766 100644 --- a/ui/base/webui/jstemplate_builder.cc +++ b/ui/base/webui/jstemplate_builder.cc
@@ -121,7 +121,15 @@ std::string GetTemplatesHtml(const base::StringPiece& html_template, const base::DictionaryValue* json, const base::StringPiece& template_id) { - std::string output(html_template.data(), html_template.size()); + ui::TemplateReplacements replacements; + ui::TemplateReplacementsFromDictionaryValue(*json, &replacements); + std::string output = + ui::ReplaceTemplateExpressions(html_template, replacements); + + // TODO(dschuyler): After the i18n-content and i18n-values are replaced with + // $i18n{} replacements, we will be able to return output at this point. + // Remove Append*() lines that builds up the i18n replacement work to be done + // in JavaScript. AppendLoadTimeData(&output); AppendJsonHtml(json, &output); AppendI18nTemplateSourceHtml(&output);
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 1c3daab9..c797a685 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -1352,7 +1352,9 @@ TRACE_EVENT_INSTANT0("input", "InputHandlerProxy::animate::flingOver", TRACE_EVENT_SCOPE_THREAD); - CancelCurrentFling(); + if (fling_parameters_.source_device != + blink::kWebGestureDeviceSyntheticAutoscroll) + CancelCurrentFling(); } }
diff --git a/ui/login/account_picker/md_screen_account_picker.css b/ui/login/account_picker/md_screen_account_picker.css index ca8742c8..17af7d7 100644 --- a/ui/login/account_picker/md_screen_account_picker.css +++ b/ui/login/account_picker/md_screen_account_picker.css
@@ -14,8 +14,8 @@ #signin-banner-container1 { height: 64px; + max-width: 450px; position: absolute; - width: 520px; z-index: 3; }
diff --git a/ui/login/account_picker/md_user_pod_row.css b/ui/login/account_picker/md_user_pod_row.css index 9ffe3aa7..933269b 100644 --- a/ui/login/account_picker/md_user_pod_row.css +++ b/ui/login/account_picker/md_user_pod_row.css
@@ -88,21 +88,20 @@ width: 100%; } -.user-image { +.pod .user-image { + border-color: rgba(255, 255, 255, .54); border-radius: 50%; - box-shadow: 0 0 2px rgba(255, 255, 255, .34); + border-style: solid; + border-width: 0.25px; + flex: none; height: 100%; width: 100%; } -.user-image.switch-image-animation { +.pod .user-image.switch-image-animation { animation: switch-image 180ms; } -.pod .user-image { - flex: none; -} - .pod .badge-container { background: #FFF; border-radius: 50%; @@ -121,15 +120,8 @@ padding: 0; } -/* Signed-in badge should be hidden when there's another badge. */ -.pod.legacy-supervised.signed-in .signed-in-badge { - display: none; -} - .pod.legacy-supervised .badge-container, -.pod.signed-in .badge-container, -.pod.legacy-supervised .legacy-supervised-badge, -.pod.signed-in .signed-in-badge { +.pod.legacy-supervised .legacy-supervised-badge { display: block; } @@ -208,10 +200,8 @@ .name { color: #FFFFFF; - /* This should be 15.6px - the equivalent of 14px at 90% scale. */ flex: auto; - font-family: "Roboto"; - font-size: 24px; + font: 24px Roboto, sans-serif; outline: none; overflow: hidden; text-align: center; @@ -259,19 +249,30 @@ width: 160px; } +.custom-icon-shown.password-container { + padding-left: 8px; + width: 145px; +} + +.capslock-on .custom-icon-shown.password-container { + width: 125px; +} + .pod input[type='password'] { background-color: transparent; border: none; color: rgba(255, 255, 255, .67); font-family: "Roboto"; - font-size: 13px; + font-size: 16px; height: 100%; - letter-spacing: 8px; + letter-spacing: 6px; padding: 0; width: 100%; } .pod input[type='password']::-webkit-input-placeholder { + color: rgba(255, 255, 255, .67); + font-size: 13px; letter-spacing: 0; } @@ -611,22 +612,6 @@ background-image: url(../../webui/resources/images/fingerprint_failed.svg); } -.pod input[type='password'].hidden::-webkit-input-placeholder { - color: grey; -} - -.pod input[type='password'].default::-webkit-input-placeholder { - color: grey; -} - -.pod input[type='password'].signin::-webkit-input-placeholder { - color: var(--google-blue-500); -} - -.pod input[type='password'].failed::-webkit-input-placeholder { - color: var(--google-red-500); -} - .action-box-menu { display: none; position: absolute; @@ -751,14 +736,16 @@ } .user-type-bubble { - background-color: white; - border: 1px solid lightgray; - border-radius: 2px; - left: 5px; + background-color: rgba(0, 0, 0, 0.9); + border-radius: 4px; + color: #FFF; + font-family: "Roboto"; + font-size: 13px; + left: 36px; opacity: 0; padding: 17px; position: absolute; - top: 20px; + top: 35px; transition: all 100ms; visibility: hidden; width: 200px; @@ -779,21 +766,15 @@ .user-type-bubble-header { font-weight: bold; margin-bottom: 14px; + text-align: center; } /**** Public account user pod rules *******************************************/ -.public-account-expanded > * { - display: none; -} - -.public-account-expanded .pod { - display: none; -} - -.public-account-expanded podrow, -.public-account-expanded .pod.public-account.expanded { - display: block; +.public-account-expanded > div, +.public-account-expanded .pod:not(.expanded) { + opacity: 0; /* Cannot be replaced with display: none, otherwise the tab + indexes of other elements in the pod row will be ignored. */ } .pod.public-account.expanded { @@ -1109,8 +1090,7 @@ .small-pod-name { color: #FFFFFF; flex: auto; - font-family: "Roboto"; - font-size: 20px; + font: 20px Roboto, sans-serif; height: 28px; left: 90px; opacity: 1;
diff --git a/ui/login/account_picker/md_user_pod_row.js b/ui/login/account_picker/md_user_pod_row.js index 5b59b4af..e9b7f6a 100644 --- a/ui/login/account_picker/md_user_pod_row.js +++ b/ui/login/account_picker/md_user_pod_row.js
@@ -28,7 +28,6 @@ var CUSTOM_ICON_CONTAINER_SIZE = 40; var CROS_PIN_POD_HEIGHT = 417; var SCROLL_MASK_HEIGHT = 112; - var BANNER_MESSAGE_WIDTH = 520; var CROS_POD_HEIGHT_WITH_PIN = 618; var PUBLIC_SESSION_ICON_WIDTH = 12; @@ -663,9 +662,7 @@ isParentPodFocused_: function() { if ($('account-picker').hidden) return false; - var parentPod = this.parentNode; - while (parentPod && !parentPod.classList.contains('pod')) - parentPod = parentPod.parentNode; + var parentPod = this.getParentPod_(); return parentPod && parentPod.parentNode.isFocused(parentPod); }, @@ -675,8 +672,11 @@ * @private */ updateTooltip_: function() { - if (this.hidden || !this.isParentPodFocused_()) + if (this.hidden || !this.getParentPod_() || + this.getParentPod_().getPodStyle() != UserPod.Style.LARGE || + !this.isParentPodFocused_()) { return; + } if (!this.tooltipState_.active() || !this.tooltipState_.text) { this.hideTooltip_(); @@ -704,6 +704,17 @@ */ hideTooltip_: function() { $('bubble').hideForElement(this); + }, + + /** + * Gets the parent pod (may be null) of this custom icon. + * @return {?HTMLDivElement} + */ + getParentPod_: function() { + var parentPod = this.parentNode; + while (parentPod && !parentPod.classList.contains('pod')) + parentPod = parentPod.parentNode; + return parentPod; } }; @@ -2241,7 +2252,7 @@ /** @override */ get mainInput() { if (this.expanded) - return this.enterButtonElement; + return this.querySelector('.monitoring-learn-more'); else return this.nameElement; }, @@ -2297,6 +2308,7 @@ monitoringLearnMore.addEventListener( 'click', this.onMonitoringLearnMoreClicked_.bind(this)); + this.enterButtonElement.tabIndex = UserPodTabOrder.POD_INPUT; this.enterButtonElement.addEventListener('click', (function(e) { this.enterButtonElement.disabled = true; var locale = this.querySelector('.language-select').value; @@ -3891,6 +3903,11 @@ actionBoxMenu.style.top = cr.ui.toCssPx(actionBoxButton.offsetHeight + MENU_TOP_PADDING); } + // Update password container width based on the visibility of the + // custom icon container. + pod.querySelector('.password-container') + .classList.toggle( + 'custom-icon-shown', !pod.customIconElement.hidden); // Add ripple animation. var actionBoxRippleEffect = pod.querySelector('.action-box-button.ripple-circle'); @@ -3907,12 +3924,12 @@ var bannerContainer = $('signin-banner-container1'); bannerContainer.style.top = cr.ui.toCssPx(this.mainPod_.top / 2); if (this.pods.length <= POD_ROW_LIMIT) { - bannerContainer.style.left = - cr.ui.toCssPx((this.screenSize.width - BANNER_MESSAGE_WIDTH) / 2); + bannerContainer.style.left = cr.ui.toCssPx( + (this.screenSize.width - bannerContainer.offsetWidth) / 2); } else { - var leftPadding = - this.mainPod_.left - (BANNER_MESSAGE_WIDTH - CROS_POD_WIDTH) / 2; + var leftPadding = this.mainPod_.left - + (bannerContainer.offsetWidth - CROS_POD_WIDTH) / 2; bannerContainer.style.left = cr.ui.toCssPx(Math.max(leftPadding, 0)); } }
diff --git a/ui/login/account_picker/md_user_pod_template.html b/ui/login/account_picker/md_user_pod_template.html index 8f92762..11a2bd6 100644 --- a/ui/login/account_picker/md_user_pod_template.html +++ b/ui/login/account_picker/md_user_pod_template.html
@@ -23,9 +23,6 @@ <g id="legacy-supervised-badge"> <path d="M16.5,13.5 C17.42,13.5 18.16,12.7533333 18.16,11.8333333 C18.16,10.9133333 17.42,10.1666667 16.5,10.1666667 C15.58,10.1666667 14.8333333,10.9133333 14.8333333,11.8333333 C14.8333333,12.7533333 15.58,13.5 16.5,13.5 Z M11.5,12.8333333 C12.6066667,12.8333333 13.4933333,11.94 13.4933333,10.8333333 C13.4933333,9.72666667 12.6066667,8.83333333 11.5,8.83333333 C10.3933333,8.83333333 9.5,9.72666667 9.5,10.8333333 C9.5,11.94 10.3933333,12.8333333 11.5,12.8333333 Z M16.5,14.8333333 C15.28,14.8333333 12.8333333,15.4466667 12.8333333,16.6666667 L12.8333333,18.1666667 L20.1666667,18.1666667 L20.1666667,16.6666667 C20.1666667,15.4466667 17.72,14.8333333 16.5,14.8333333 Z M11.5,14.1666667 C9.94666667,14.1666667 6.83333333,14.9466667 6.83333333,16.5 L6.83333333,18.1666667 L11.5,18.1666667 L11.5,16.6666667 C11.5,16.1 11.72,15.1066667 13.08,14.3533333 C12.5,14.2333333 11.94,14.1666667 11.5,14.1666667 Z" id="Shape" fill="#000000" fill-rule="nonzero" opacity="0.34"></path> </g> - <g id="signed-in-badge"> - <polygon id="Shape" fill="#000000" fill-rule="nonzero" opacity="0.34" points="11.5 16.28 8.72 13.5 7.77333333 14.44 11.5 18.1666667 19.5 10.1666667 18.56 9.22666667"></polygon> - </g> <g id="caps-lock"> <path d="M2.5,4.49188419 C2.5,3.39179693 3.39339733,2.5 4.49188419,2.5 L15.5081158,2.5 C16.6082031,2.5 17.5,3.39339733 17.5,4.49188419 L17.5,15.5081158 C17.5,16.6082031 16.6066027,17.5 15.5081158,17.5 L4.49188419,17.5 C3.39179693,17.5 2.5,16.6066027 2.5,15.5081158 L2.5,4.49188419 Z M10,7.47368421 L13.825,11.5 L15,10.2631579 L10,5 L5,10.2631579 L6.175,11.5 L10,7.47368421 Z M5,15 L15,15 L15,13.5 L5,13.5 L5,15 Z" id="Combined-Shape" fill="#FFFFFF"></path> </g> @@ -47,8 +44,6 @@ <iron-icon class="legacy-supervised-badge" icon="user-pod:legacy-supervised-badge"> </iron-icon> - <iron-icon class="signed-in-badge" icon="user-pod:signed-in-badge"> - </iron-icon> </div> </div> <if expr="chromeos"> @@ -257,7 +252,7 @@ <div class="enter-button-container"> <paper-icon-button class="public-account-submit-button enter-button" aria-label="$i18n{publicAccountEnterAccessibleName}" - icon="user-pod:arrow-forward" tabindex="-1"> + icon="user-pod:arrow-forward"> </paper-icon-button> </div> </div>
diff --git a/ui/login/md_screen_container.css b/ui/login/md_screen_container.css index 14fb05b..8c10b4a 100644 --- a/ui/login/md_screen_container.css +++ b/ui/login/md_screen_container.css
@@ -81,10 +81,8 @@ #oobe.auto-enrollment-check #inner-container, #oobe.autolaunch #inner-container, #oobe.confirm-password #inner-container, -#oobe:not([md-mode]).connect #inner-container, #oobe.debugging #inner-container, #oobe.enrollment #inner-container, -#oobe:not([md-mode]).eula #inner-container, #oobe.fatal-error #inner-container, #oobe.gaia-signin #inner-container, #oobe.hid-detection #inner-container, @@ -92,7 +90,6 @@ #oobe.oauth-enrollment #inner-container, #oobe.password-changed #inner-container, #oobe.ad-password-change #inner-container, -#oobe.reset #inner-container, #oobe.supervised-user-creation #inner-container, #oobe.supervised-user-creation-dialog #inner-container, #oobe.terms-of-service #inner-container, @@ -124,13 +121,6 @@ transform: translateY(50px) rotateX(-2.5deg); } -#oobe:not([md-mode]) #step-logo { - -webkit-margin-start: 17px; - display: -webkit-box; - position: absolute; - top: 15px; -} - #oobe[md-mode] #step-logo { display: none; }
diff --git a/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js b/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js index 7a31ab5..854a812d 100644 --- a/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js +++ b/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js
@@ -31,308 +31,308 @@ }; (function() { +/** + * Returns the point to start along the X or Y axis given a start and end + * point to anchor to, the length of the target and the direction to anchor + * in. If honoring the anchor would force the menu outside of min/max, this + * will ignore the anchor position and try to keep the menu within min/max. + * @private + * @param {number} start + * @param {number} end + * @param {number} length + * @param {AnchorAlignment} anchorAlignment + * @param {number} min + * @param {number} max + * @return {number} + */ +function getStartPointWithAnchor( + start, end, length, anchorAlignment, min, max) { + var startPoint = 0; + switch (anchorAlignment) { + case AnchorAlignment.BEFORE_START: + startPoint = -length; + break; + case AnchorAlignment.AFTER_START: + startPoint = start; + break; + case AnchorAlignment.CENTER: + startPoint = (start + end - length) / 2; + break; + case AnchorAlignment.BEFORE_END: + startPoint = end - length; + break; + case AnchorAlignment.AFTER_END: + startPoint = end; + break; + } + + if (startPoint + length > max) + startPoint = end - length; + if (startPoint < min) + startPoint = start; + return startPoint; +} + + +/** + * @private + * @return {!ShowConfig} + */ +function getDefaultShowConfig() { + return { + top: 0, + left: 0, + height: 0, + width: 0, + anchorAlignmentX: AnchorAlignment.AFTER_START, + anchorAlignmentY: AnchorAlignment.AFTER_START, + minX: 0, + minY: 0, + maxX: window.innerWidth, + maxY: window.innerHeight, + }; +} + +Polymer({ + is: 'cr-action-menu', + extends: 'dialog', + /** - * Returns the point to start along the X or Y axis given a start and end - * point to anchor to, the length of the target and the direction to anchor - * in. If honoring the anchor would force the menu outside of min/max, this - * will ignore the anchor position and try to keep the menu within min/max. - * @private - * @param {number} start - * @param {number} end - * @param {number} length - * @param {AnchorAlignment} anchorAlignment - * @param {number} min - * @param {number} max - * @return {number} + * List of all options in this action menu. + * @private {?NodeList<!Element>} */ - function getStartPointWithAnchor( - start, end, length, anchorAlignment, min, max) { - var startPoint = 0; - switch (anchorAlignment) { - case AnchorAlignment.BEFORE_START: - startPoint = -length; - break; - case AnchorAlignment.AFTER_START: - startPoint = start; - break; - case AnchorAlignment.CENTER: - startPoint = (start + end - length) / 2; - break; - case AnchorAlignment.BEFORE_END: - startPoint = end - length; - break; - case AnchorAlignment.AFTER_END: - startPoint = end; - break; + options_: null, + + /** + * The element which the action menu will be anchored to. Also the element + * where focus will be returned after the menu is closed. Only populated if + * menu is opened with showAt(). + * @private {?Element} + */ + anchorElement_: null, + + /** + * Bound reference to an event listener function such that it can be removed + * on detach. + * @private {?Function} + */ + boundClose_: null, + + /** @private {boolean} */ + hasMousemoveListener_: false, + + hostAttributes: { + tabindex: 0, + }, + + listeners: { + 'keydown': 'onKeyDown_', + 'mouseover': 'onMouseover_', + 'tap': 'onTap_', + }, + + /** override */ + attached: function() { + this.options_ = this.querySelectorAll('.dropdown-item'); + }, + + /** override */ + detached: function() { + this.removeListeners_(); + }, + + /** @private */ + removeListeners_: function() { + window.removeEventListener('resize', this.boundClose_); + window.removeEventListener('popstate', this.boundClose_); + }, + + /** + * @param {!Event} e + * @private + */ + onTap_: function(e) { + if (e.target == this) { + this.close(); + e.stopPropagation(); + } + }, + + /** + * @param {!KeyboardEvent} e + * @private + */ + onKeyDown_: function(e) { + if (e.key == 'Tab' || e.key == 'Escape') { + this.close(); + e.preventDefault(); + return; } - if (startPoint + length > max) - startPoint = end - length; - if (startPoint < min) - startPoint = start; - return startPoint; - } + if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') + return; + var nextOption = this.getNextOption_(e.key == 'ArrowDown' ? 1 : -1); + if (nextOption) { + if (!this.hasMousemoveListener_) { + this.hasMousemoveListener_ = true; + listenOnce(this, 'mousemove', function(e) { + this.onMouseover_(e); + this.hasMousemoveListener_ = false; + }.bind(this)); + } + nextOption.focus(); + } + + e.preventDefault(); + }, /** + * @param {!Event} e * @private - * @return {!ShowConfig} */ - function getDefaultShowConfig() { - return { - top: 0, - left: 0, - height: 0, - width: 0, - anchorAlignmentX: AnchorAlignment.AFTER_START, - anchorAlignmentY: AnchorAlignment.AFTER_START, - minX: 0, - minY: 0, - maxX: window.innerWidth, - maxY: window.innerHeight, - }; - } - - Polymer({ - is: 'cr-action-menu', - extends: 'dialog', - - /** - * List of all options in this action menu. - * @private {?NodeList<!Element>} - */ - options_: null, - - /** - * The element which the action menu will be anchored to. Also the element - * where focus will be returned after the menu is closed. Only populated if - * menu is opened with showAt(). - * @private {?Element} - */ - anchorElement_: null, - - /** - * Bound reference to an event listener function such that it can be removed - * on detach. - * @private {?Function} - */ - boundClose_: null, - - /** @private {boolean} */ - hasMousemoveListener_: false, - - hostAttributes: { - tabindex: 0, - }, - - listeners: { - 'keydown': 'onKeyDown_', - 'mouseover': 'onMouseover_', - 'tap': 'onTap_', - }, - - /** override */ - attached: function() { - this.options_ = this.querySelectorAll('.dropdown-item'); - }, - - /** override */ - detached: function() { - this.removeListeners_(); - }, - - /** @private */ - removeListeners_: function() { - window.removeEventListener('resize', this.boundClose_); - window.removeEventListener('popstate', this.boundClose_); - }, - - /** - * @param {!Event} e - * @private - */ - onTap_: function(e) { - if (e.target == this) { - this.close(); - e.stopPropagation(); - } - }, - - /** - * @param {!KeyboardEvent} e - * @private - */ - onKeyDown_: function(e) { - if (e.key == 'Tab' || e.key == 'Escape') { - this.close(); - e.preventDefault(); + onMouseover_: function(e) { + // TODO(scottchen): Using "focus" to determine selected item might mess + // with screen readers in some edge cases. + var i = 0; + do { + var target = e.path[i++]; + if (target.classList && target.classList.contains('dropdown-item')) { + target.focus(); return; } + } while (this != target); - if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') - return; + // The user moved the mouse off the options. Reset focus to the dialog. + this.focus(); + }, - var nextOption = this.getNextOption_(e.key == 'ArrowDown' ? 1 : -1); - if (nextOption) { - if (!this.hasMousemoveListener_) { - this.hasMousemoveListener_ = true; - listenOnce(this, 'mousemove', function(e) { - this.onMouseover_(e); - this.hasMousemoveListener_ = false; - }.bind(this)); - } - nextOption.focus(); - } + /** + * @param {number} step -1 for getting previous option (up), 1 for getting + * next option (down). + * @return {?Element} The next focusable option, taking into account + * disabled/hidden attributes, or null if no focusable option exists. + * @private + */ + getNextOption_: function(step) { + // Using a counter to ensure no infinite loop occurs if all elements are + // hidden/disabled. + var counter = 0; + var nextOption = null; + var numOptions = this.options_.length; + var focusedIndex = + Array.prototype.indexOf.call(this.options_, this.root.activeElement); - e.preventDefault(); - }, + // Handle case where nothing is focused and up is pressed. + if (focusedIndex === -1 && step === -1) + focusedIndex = 0; - /** - * @param {!Event} e - * @private - */ - onMouseover_: function(e) { - // TODO(scottchen): Using "focus" to determine selected item might mess - // with screen readers in some edge cases. - var i = 0; - do { - var target = e.path[i++]; - if (target.classList && target.classList.contains('dropdown-item')) { - target.focus(); - return; - } - } while (this != target); + do { + focusedIndex = (numOptions + focusedIndex + step) % numOptions; + nextOption = this.options_[focusedIndex]; + if (nextOption.disabled || nextOption.hidden) + nextOption = null; + counter++; + } while (!nextOption && counter < numOptions); - // The user moved the mouse off the options. Reset focus to the dialog. - this.focus(); - }, + return nextOption; + }, - /** - * @param {number} step -1 for getting previous option (up), 1 for getting - * next option (down). - * @return {?Element} The next focusable option, taking into account - * disabled/hidden attributes, or null if no focusable option exists. - * @private - */ - getNextOption_: function(step) { - // Using a counter to ensure no infinite loop occurs if all elements are - // hidden/disabled. - var counter = 0; - var nextOption = null; - var numOptions = this.options_.length; - var focusedIndex = - Array.prototype.indexOf.call(this.options_, this.root.activeElement); + /** @override */ + close: function() { + // Removing 'resize' and 'popstate' listeners when dialog is closed. + this.removeListeners_(); + HTMLDialogElement.prototype.close.call(this); + if (this.anchorElement_) { + cr.ui.focusWithoutInk(assert(this.anchorElement_)); + this.anchorElement_ = null; + } + }, - // Handle case where nothing is focused and up is pressed. - if (focusedIndex === -1 && step === -1) - focusedIndex = 0; + /** + * Shows the menu anchored to the given element. + * @param {!Element} anchorElement + */ + showAt: function(anchorElement) { + this.anchorElement_ = anchorElement; + this.anchorElement_.scrollIntoViewIfNeeded(); + var rect = this.anchorElement_.getBoundingClientRect(); + this.showAtPosition({ + top: rect.top, + left: rect.left, + height: rect.height, + width: rect.width, + // Default to anchoring towards the left. + anchorAlignmentX: AnchorAlignment.BEFORE_END, + }); + }, - do { - focusedIndex = (numOptions + focusedIndex + step) % numOptions; - nextOption = this.options_[focusedIndex]; - if (nextOption.disabled || nextOption.hidden) - nextOption = null; - counter++; - } while (!nextOption && counter < numOptions); + /** + * Shows the menu anchored to the given box. The anchor alignment is + * specified as an X and Y alignment which represents a point in the anchor + * where the menu will align to, which can have the menu either before or + * after the given point in each axis. Center alignment places the center of + * the menu in line with the center of the anchor. + * + * y-start + * _____________ + * | | + * | | + * | CENTER | + * x-start | x | x-end + * | | + * |anchor box | + * |___________| + * + * y-end + * + * For example, aligning the menu to the inside of the top-right edge of + * the anchor, extending towards the bottom-left would use a alignment of + * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom + * edge of the anchor would use (CENTER, AFTER_END). + * + * @param {!ShowConfig} config + */ + showAtPosition: function(config) { + var c = Object.assign(getDefaultShowConfig(), config); - return nextOption; - }, + var top = c.top; + var left = c.left; + var bottom = top + c.height; + var right = left + c.width; - /** @override */ - close: function() { - // Removing 'resize' and 'popstate' listeners when dialog is closed. - this.removeListeners_(); - HTMLDialogElement.prototype.close.call(this); - if (this.anchorElement_) { - cr.ui.focusWithoutInk(assert(this.anchorElement_)); - this.anchorElement_ = null; - } - }, + this.boundClose_ = this.boundClose_ || function() { + if (this.open) + this.close(); + }.bind(this); + window.addEventListener('resize', this.boundClose_); + window.addEventListener('popstate', this.boundClose_); - /** - * Shows the menu anchored to the given element. - * @param {!Element} anchorElement - */ - showAt: function(anchorElement) { - this.anchorElement_ = anchorElement; - this.anchorElement_.scrollIntoViewIfNeeded(); - var rect = this.anchorElement_.getBoundingClientRect(); - this.showAtPosition({ - top: rect.top, - left: rect.left, - height: rect.height, - width: rect.width, - // Default to anchoring towards the left. - anchorAlignmentX: AnchorAlignment.BEFORE_END, - }); - }, + // Reset position to prevent previous values from affecting layout. + this.style.left = ''; + this.style.right = ''; + this.style.top = ''; - /** - * Shows the menu anchored to the given box. The anchor alignment is - * specified as an X and Y alignment which represents a point in the anchor - * where the menu will align to, which can have the menu either before or - * after the given point in each axis. Center alignment places the center of - * the menu in line with the center of the anchor. - * - * y-start - * _____________ - * | | - * | | - * | CENTER | - * x-start | x | x-end - * | | - * |anchor box | - * |___________| - * - * y-end - * - * For example, aligning the menu to the inside of the top-right edge of - * the anchor, extending towards the bottom-left would use a alignment of - * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom - * edge of the anchor would use (CENTER, AFTER_END). - * - * @param {!ShowConfig} config - */ - showAtPosition: function(config) { - var c = Object.assign(getDefaultShowConfig(), config); + this.showModal(); - var top = c.top; - var left = c.left; - var bottom = top + c.height; - var right = left + c.width; + // Flip the X anchor in RTL. + var rtl = getComputedStyle(this).direction == 'rtl'; + if (rtl) + c.anchorAlignmentX *= -1; - this.boundClose_ = this.boundClose_ || function() { - if (this.open) - this.close(); - }.bind(this); - window.addEventListener('resize', this.boundClose_); - window.addEventListener('popstate', this.boundClose_); + var menuLeft = getStartPointWithAnchor( + left, right, this.offsetWidth, c.anchorAlignmentX, c.minX, c.maxX); - // Reset position to prevent previous values from affecting layout. - this.style.left = ''; - this.style.right = ''; - this.style.top = ''; + if (rtl) { + var menuRight = window.innerWidth - menuLeft - this.offsetWidth; + this.style.right = menuRight + 'px'; + } else { + this.style.left = menuLeft + 'px'; + } - this.showModal(); - - // Flip the X anchor in RTL. - var rtl = getComputedStyle(this).direction == 'rtl'; - if (rtl) - c.anchorAlignmentX *= -1; - - var menuLeft = getStartPointWithAnchor( - left, right, this.offsetWidth, c.anchorAlignmentX, c.minX, c.maxX); - - if (rtl) { - var menuRight = window.innerWidth - menuLeft - this.offsetWidth; - this.style.right = menuRight + 'px'; - } else { - this.style.left = menuLeft + 'px'; - } - - var menuTop = getStartPointWithAnchor( - top, bottom, this.offsetHeight, c.anchorAlignmentY, c.minY, c.maxY); - this.style.top = menuTop + 'px'; - }, - }); + var menuTop = getStartPointWithAnchor( + top, bottom, this.offsetHeight, c.anchorAlignmentY, c.minY, c.maxY); + this.style.top = menuTop + 'px'; + }, +}); })();
diff --git a/ui/webui/resources/cr_elements/cr_scrollable_behavior.js b/ui/webui/resources/cr_elements/cr_scrollable_behavior.js index 38eb177..2a49780 100644 --- a/ui/webui/resources/cr_elements/cr_scrollable_behavior.js +++ b/ui/webui/resources/cr_elements/cr_scrollable_behavior.js
@@ -101,7 +101,7 @@ requestAnimationFrame(function() { var scrollableElements = this.root.querySelectorAll('[scrollable]'); for (var i = 0; i < scrollableElements.length; i++) - this.updateScroll_(/** @type {!HTMLElement} */(scrollableElements[i])); + this.updateScroll_(/** @type {!HTMLElement} */ (scrollableElements[i])); }.bind(this)); }, @@ -145,7 +145,8 @@ 'can-scroll', scrollable.clientHeight < scrollable.scrollHeight); scrollable.classList.toggle('is-scrolled', scrollable.scrollTop > 0); scrollable.classList.toggle( - 'scrolled-to-bottom', scrollable.scrollTop + scrollable.clientHeight >= + 'scrolled-to-bottom', + scrollable.scrollTop + scrollable.clientHeight >= scrollable.scrollHeight); }, };
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js index dff9bc2..f52c63fb 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.js
@@ -80,8 +80,10 @@ { opacity: [0, .9], }, - /** @type {!KeyframeEffectOptions} */ ( - {duration: 500, fill: 'forwards'})); + /** @type {!KeyframeEffectOptions} */ ({ + duration: 500, + fill: 'forwards' + })); this.fire('cr-toolbar-menu-promo-shown'); } }.bind(this));
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js index 3ff9f99..f3fa59b 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js +++ b/ui/webui/resources/cr_elements/policy/cr_policy_network_behavior.js
@@ -75,8 +75,9 @@ * @private */ isPolicySource: function(source) { - return !!source && (source == CrOnc.Source.DEVICE_POLICY || - source == CrOnc.Source.USER_POLICY); + return !!source && + (source == CrOnc.Source.DEVICE_POLICY || + source == CrOnc.Source.USER_POLICY); }, /**
diff --git a/ui/webui/resources/js/analytics.js b/ui/webui/resources/js/analytics.js index c8bda26d..b0893a6 100644 --- a/ui/webui/resources/js/analytics.js +++ b/ui/webui/resources/js/analytics.js
@@ -11,4 +11,3 @@ // of a licence header. // clang-format off <include src="../../../../third_party/analytics/google-analytics-bundle.js"> -// clang-format on
diff --git a/ui/webui/resources/js/cr/ui/bubble.js b/ui/webui/resources/js/cr/ui/bubble.js index abb8a5a..055f1cb5 100644 --- a/ui/webui/resources/js/cr/ui/bubble.js +++ b/ui/webui/resources/js/cr/ui/bubble.js
@@ -191,9 +191,9 @@ left = Math.max(Math.min(left, maxLeftPos), minLeftPos); var arrowTip = Math.min( Math.max( - arrow.width / 2, this.arrowAtRight_ ? - left + bubble.width - anchorMid : - anchorMid - left), + arrow.width / 2, + this.arrowAtRight_ ? left + bubble.width - anchorMid : + anchorMid - left), bubble.width - arrow.width / 2); // Work out the vertical placement, attempting to fit the bubble
diff --git a/ui/webui/resources/js/cr/ui/command.js b/ui/webui/resources/js/cr/ui/command.js index 783bba5..cdf55b19 100644 --- a/ui/webui/resources/js/cr/ui/command.js +++ b/ui/webui/resources/js/cr/ui/command.js
@@ -65,6 +65,32 @@ }; /** + * A list of keyboard shortcuts which all perform one command. + * @param {string} shortcuts Text-based representation of one or more keyboard + * shortcuts, separated by spaces. + * @constructor + */ + function KeyboardShortcutList(shortcuts) { + this.shortcuts_ = shortcuts.split(/\s+/).map(function(shortcut) { + return new KeyboardShortcut(shortcut); + }); + } + + KeyboardShortcutList.prototype = { + /** + * Returns true if any of the keyboard shortcuts in the list matches a + * keyboard event. + * @param {!Event} e + * @return {boolean} + */ + matchesEvent: function(e) { + return this.shortcuts_.some(function(keyboardShortcut) { + return keyboardShortcut.matchesEvent(e); + }); + }, + }; + + /** * Creates a new command element. * @constructor * @extends {HTMLElement} @@ -135,9 +161,7 @@ set shortcut(shortcut) { var oldShortcut = this.shortcut_; if (shortcut !== oldShortcut) { - this.keyboardShortcuts_ = shortcut.split(/\s+/).map(function(shortcut) { - return new KeyboardShortcut(shortcut); - }); + this.keyboardShortcuts_ = new KeyboardShortcutList(shortcut); // Set this after the keyboardShortcuts_ since that might throw. this.shortcut_ = shortcut; @@ -154,10 +178,7 @@ matchesEvent: function(e) { if (!this.keyboardShortcuts_) return false; - - return this.keyboardShortcuts_.some(function(keyboardShortcut) { - return keyboardShortcut.matchesEvent(e); - }); + return this.keyboardShortcuts_.matchesEvent(e); }, }; @@ -323,5 +344,9 @@ }; // Export - return {Command: Command, CanExecuteEvent: CanExecuteEvent}; + return { + Command: Command, + CanExecuteEvent: CanExecuteEvent, + KeyboardShortcutList: KeyboardShortcutList, + }; });
diff --git a/ui/webui/resources/js/cr/ui/touch_handler.js b/ui/webui/resources/js/cr/ui/touch_handler.js index dc7c818..b30251d 100644 --- a/ui/webui/resources/js/cr/ui/touch_handler.js +++ b/ui/webui/resources/js/cr/ui/touch_handler.js
@@ -67,9 +67,9 @@ * recent relevant touch and the second item is the touch's time stamp. Old * touches are removed based on the max tracking time and when direction * changes. - * @type {!Array<number>} - * @private - */ + * @type {!Array<number>} + * @private + */ this.recentTouchesX_ = []; /**
diff --git a/ui/webui/resources/js/jstemplate_compiled.js b/ui/webui/resources/js/jstemplate_compiled.js index a1344c7..5934475 100644 --- a/ui/webui/resources/js/jstemplate_compiled.js +++ b/ui/webui/resources/js/jstemplate_compiled.js
@@ -11,4 +11,3 @@ // of a licence header. // clang-format off <include src="../../../../third_party/jstemplate/jstemplate_compiled.js"> -// clang-format on
diff --git a/ui/webui/resources/js/webui_resource_test.js b/ui/webui/resources/js/webui_resource_test.js index b4fadbd..12b3c37 100644 --- a/ui/webui/resources/js/webui_resource_test.js +++ b/ui/webui/resources/js/webui_resource_test.js
@@ -119,88 +119,88 @@ * Defines runTests. */ (function(exports) { - /** - * List of test cases. - * @type {Array<string>} List of function names for tests to run. - */ - var testCases = []; +/** + * List of test cases. + * @type {Array<string>} List of function names for tests to run. + */ +var testCases = []; - /** - * Indicates if all tests have run successfully. - * @type {boolean} - */ - var cleanTestRun = true; +/** + * Indicates if all tests have run successfully. + * @type {boolean} + */ +var cleanTestRun = true; - /** - * Armed during setup of a test to call the matching tear down code. - * @type {Function} - */ - var pendingTearDown = null; +/** + * Armed during setup of a test to call the matching tear down code. + * @type {Function} + */ +var pendingTearDown = null; - /** - * Runs all functions starting with test and reports success or - * failure of the test suite. - */ - function runTests() { - for (var name in window) { - // To avoid unnecessary getting properties, test name first. - if (/^test/.test(name) && typeof window[name] == 'function') - testCases.push(name); - } - if (!testCases.length) { - console.error('Failed to find test cases.'); - cleanTestRun = false; - } +/** + * Runs all functions starting with test and reports success or + * failure of the test suite. + */ +function runTests() { + for (var name in window) { + // To avoid unnecessary getting properties, test name first. + if (/^test/.test(name) && typeof window[name] == 'function') + testCases.push(name); + } + if (!testCases.length) { + console.error('Failed to find test cases.'); + cleanTestRun = false; + } + try { + if (window.setUpPage) + window.setUpPage(); + } catch (err) { + cleanTestRun = false; + } + continueTesting(); +} + +/** + * Runs the next test in the queue. Reports the test results if the queue is + * empty. + * @param {boolean=} opt_asyncTestFailure Optional parameter indicated if the + * last asynchronous test failed. + */ +function continueTesting(opt_asyncTestFailure) { + if (opt_asyncTestFailure) + cleanTestRun = false; + var done = false; + if (pendingTearDown) { + pendingTearDown(); + pendingTearDown = null; + } + if (testCases.length > 0) { + var fn = testCases.pop(); + var isAsyncTest = window[fn].length; try { - if (window.setUpPage) - window.setUpPage(); + if (window.setUp) + window.setUp(); + pendingTearDown = window.tearDown; + window[fn](continueTesting); } catch (err) { + console.error('Failure in test ' + fn + '\n' + err); + console.log(err.stack); cleanTestRun = false; } - continueTesting(); + // Asynchronous tests must manually call continueTesting when complete. + if (!isAsyncTest) + continueTesting(); + } else { + done = true; + endTests(cleanTestRun); } - - /** - * Runs the next test in the queue. Reports the test results if the queue is - * empty. - * @param {boolean=} opt_asyncTestFailure Optional parameter indicated if the - * last asynchronous test failed. - */ - function continueTesting(opt_asyncTestFailure) { - if (opt_asyncTestFailure) - cleanTestRun = false; - var done = false; - if (pendingTearDown) { - pendingTearDown(); - pendingTearDown = null; - } - if (testCases.length > 0) { - var fn = testCases.pop(); - var isAsyncTest = window[fn].length; - try { - if (window.setUp) - window.setUp(); - pendingTearDown = window.tearDown; - window[fn](continueTesting); - } catch (err) { - console.error('Failure in test ' + fn + '\n' + err); - console.log(err.stack); - cleanTestRun = false; - } - // Asynchronous tests must manually call continueTesting when complete. - if (!isAsyncTest) - continueTesting(); - } else { - done = true; - endTests(cleanTestRun); - } - if (!done) { - domAutomationController.setAutomationId(1); - domAutomationController.send('PENDING'); - } + if (!done) { + domAutomationController.setAutomationId(1); + domAutomationController.send('PENDING'); } +} - exports.runTests = runTests; +exports.runTests = runTests; })(this); /**