├── .github └── workflows │ └── build.yaml ├── .gitignore ├── LICENSE ├── LICENSE.header ├── README.md ├── gwt-core-gwt2-tests ├── pom.xml └── src │ └── test │ ├── java │ └── org │ │ └── gwtproject │ │ └── core │ │ ├── CoreSuite.java │ │ └── client │ │ ├── GWTTest.java │ │ ├── JavaScriptObjectTest.java │ │ ├── JsArrayMixedTest.java │ │ ├── JsArrayTest.java │ │ ├── JsonUtilsTest.java │ │ ├── SchedulerTest.java │ │ ├── ScriptInjectorTest.java │ │ └── impl │ │ └── SchedulerImplTest.java │ └── resources │ └── org │ └── gwtproject │ └── core │ └── public │ ├── script_injector_test4.js │ ├── script_injector_test5.js │ ├── script_injector_test6.js │ ├── script_injector_test7.js │ ├── script_injector_test_absolute.js │ ├── script_injector_test_absolute_top.js │ └── script_injector_test_utf8.js ├── gwt-core-j2cl-tests ├── pom.xml └── src │ └── test │ ├── java │ └── org │ │ └── gwtproject │ │ └── core │ │ └── client │ │ ├── GWTTest.java │ │ ├── JavaScriptObjectTest.java │ │ ├── JsArrayMixedTest.java │ │ ├── JsArrayTest.java │ │ ├── JsonUtilsTest.java │ │ ├── SchedulerTest.java │ │ └── ScriptInjectorTest.java │ └── resources │ └── org │ └── gwtproject │ └── core │ └── public │ ├── script_injector_test4.js │ ├── script_injector_test5.js │ ├── script_injector_test6.js │ ├── script_injector_test7.js │ ├── script_injector_test_absolute.js │ ├── script_injector_test_absolute_top.js │ └── script_injector_test_utf8.js ├── gwt-core ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── gwtproject │ │ │ └── core │ │ │ ├── client │ │ │ ├── Callback.java │ │ │ ├── Duration.java │ │ │ ├── GWT.java │ │ │ ├── GWT.native.js │ │ │ ├── JavaScriptObject.java │ │ │ ├── JsArray.java │ │ │ ├── JsArrayBoolean.java │ │ │ ├── JsArrayInteger.java │ │ │ ├── JsArrayMixed.java │ │ │ ├── JsArrayNumber.java │ │ │ ├── JsArrayString.java │ │ │ ├── JsArrayUtils.java │ │ │ ├── JsDate.java │ │ │ ├── JsonUtils.java │ │ │ ├── Scheduler.java │ │ │ ├── ScriptInjector.java │ │ │ └── impl │ │ │ │ └── SchedulerImpl.java │ │ │ └── shared │ │ │ ├── GWT.java │ │ │ ├── GwtIncompatible.java │ │ │ └── gwtcore.js │ └── module.gwt.xml │ └── test │ └── java │ └── org │ └── gwtproject │ └── core │ └── shared │ └── GWTTest.java └── pom.xml /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2018 The GWT Project Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | name: CI 18 | 19 | on: [push, pull_request] 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v2 27 | 28 | # TODO: cache dependencies (taking into accounts: Maven plugins, snapshots, etc.) 29 | 30 | - name: Build with Maven 31 | run: JAVA_HOME=$JAVA_HOME_8_X64 mvn -V -B -ntp -U -e verify 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # NOTE: we don't include IDE-specific files (e.g. IntelliJ's *.iml and .idea/) on-purpose. 2 | # Those patterns should go in a global gitignore or repository-specific excludes. 3 | # See http://www.gwtproject.org/makinggwtbetter.html#global_gitignore 4 | 5 | target/ 6 | .flattened-pom.xml 7 | 8 | # gwt caches and compiled units # 9 | war/ 10 | gwt-unitCache/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /LICENSE.header: -------------------------------------------------------------------------------- 1 | Copyright © ${year} ${name} 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GWT Core 2 | 3 | ![GWT3/J2CL compatible](https://img.shields.io/badge/GWT3/J2CL-compatible-brightgreen.svg) [![License](https://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) [![Chat on Gitter](https://badges.gitter.im/hal/elemento.svg)](https://gitter.im/gwtproject/gwt-modules) ![CI](https://github.com/gwtproject/gwt-core/workflows/CI/badge.svg) 4 | 5 | A future-proof port of the `com.google.gwt.core.Core` GWT module, with no dependency on `gwt-user` (besides the Java Runtime Emulation), to prepare for GWT 3 / J2Cl. 6 | 7 | This project is meant to roughly approximate the various classes and methods found in gwt-user's `com.google.gwt.core` 8 | packages. In some cases, updated replacements are provided, in other cases working, but deprecated versions are offered, 9 | and further classes or members are outright skipped, encouraging projects to either find an alternative way to manage 10 | these operations before updating, or switch to a GWT3-version while performing the actual migration. 11 | 12 | This project is not yet complete, there are doubtlessly better ways to handle some cases here. 13 | 14 | ## Migrating from `com.google.gwt.core.Core` 15 | 16 | 1. Add the dependency to your build. 17 | 18 | For Maven: 19 | 20 | ```xml 21 | 22 | org.gwtproject.core 23 | gwt-core 24 | HEAD-SNAPSHOT 25 | 26 | ``` 27 | 28 | For Gradle: 29 | 30 | ```gradle 31 | implementation("org.gwtproject.core:gwt-core:HEAD-SNAPSHOT") 32 | ``` 33 | 34 | 2. Update your GWT module to use 35 | 36 | ```xml 37 | 38 | ``` 39 | 40 | 3. Change the `import`s in your Java source files: 41 | 42 | ```java 43 | import org.gwtproject.core.client.GWT; 44 | ``` 45 | 46 | ## Instructions 47 | 48 | To build gwt-core: 49 | 50 | * run `mvn clean verify` 51 | 52 | on the parent directory. This will build the artifact and run tests against the JVM, J2CL, and GWT2. 53 | 54 | ## System Requirements 55 | 56 | **GWT Core requires GWT 2.9.0 or newer!** 57 | 58 | 59 | ## Dependencies 60 | 61 | GWT Core does not depend on any other module. 62 | 63 | 64 | ## Listing of classes from gwt-user's core 65 | 66 | * client 67 | * debug 68 | * JsoInspector - Skipped, at least for now, I'm not aware of any developer tools actually making use of this 69 | * impl 70 | * AsyncFragmentLoader - Skipped, used primarily by Split Points, not yet present in GWT3 71 | * CrossSiteLoadingStrategy - Skipped, split points 72 | * Impl - Skipped, internal details of GWT2, cannot be expected to exist at all in GWT3 73 | * JavaScriptExceptionBase - Skipped, exceptions are handled differently in GWT3, legacy dev mode is not a concern 74 | * LoadingStrategyBase - Skipped, split points 75 | * OnSuccessExecutor - Skipped, package-protected and used in split points 76 | * SchedulerImpl - Updated, missing scheduleEntry 77 | * ScriptTagLoadingStrategy - Skipped, split points 78 | * StackTraceCreator - Skipped, browsers are less crappy now 79 | * SuperDevModeLogger - Skipped, GWT.log either will not exist, or will only be implemented in this way anyway 80 | * SynchronousOnSuccessExecutor - Skipped, package-protected, split points 81 | * WeakMapping - TODO consider providing this, consider an approach similar to how J2CL handles hashcodes 82 | * XhrLoadingStrategy - Skipped, split points 83 | * prefetch - package skipped, split points 84 | * testing 85 | * StubScheduler - included, deliberately skipping scheduleEntry to match ScheduleImpl 86 | * AsyncProvided - Skipped, split points 87 | * Callback - Included, simple interface that eventually probably should be moved anyway 88 | * CodeDownloadExecution - Skipped, split points 89 | * Duration - Included for now, only as a util class for Scheduler 90 | * EntryPoint - Removed - GWT2 applications must continue to use `com.google.gwt.core.client.EntryPoint`, whereas 91 | while J2CL applications have much more flexibility, they will probably use a different pattern. 92 | * GWT - Partially included for now to ease migration. This likely belongs in the "third" category, code which largely 93 | will not exist in GWT 3, so should be removed now, but this is used so extensively that would be difficult. Methods 94 | which can be supported are included, with others removed. Deprecated methods are either broken or should be phased 95 | out. 96 | * JavaScriptException - Skipped for now, unsure we can replace in a way that will still behave the same as before 97 | * JavaScriptObject - Included, deprecated: classes extending this will need additional updates to properly conform 98 | to JsInterop requirements 99 | * JsArray - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` 100 | * JsArrayBoolean - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` 101 | * JsArrayInteger - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` 102 | and cast or coerce appropriately 103 | * JsArrayMixed - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` or 104 | use `getAnyAt(int)` 105 | * JsArrayNumber - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` 106 | * JsArrayString - Updated, deprecated: projects should migrate when feasible to `elemental2.core.JsArray` 107 | * JsArrayUtils - Updated, deprecated, consists only of calls to Js.uncheckedCast 108 | * JsDate - Updated, deprecated: projects should migrate to `elemental2.core.JsDate` 109 | * JsonUtils - Updated, deprecated: projects should migrate to elemental2's JSON.parse and JSON.stringify, no method 110 | in this class actually uses eval any longer 111 | * RunAsyncCallback - Skipped, split points 112 | * Scheduler - Updated, mising scheduleEntry 113 | * ScriptInjector - Updated 114 | * SingleJsoImpl - Skipped, JSO-related, shouldn't be needed 115 | * SingleJsoImplName - Skipped, JSO-related, shouldn't be needed 116 | 117 | 118 | As with other ported modules, the expectation for the initial release is to as closely match as possible the API of the 119 | original code, minus package structure, even when a better replacement exists. This will enable projects to first 120 | migrate to the new packages, then later update to newer versions of the migrated modules where further changes and 121 | improvements are made. 122 | 123 | 124 | ## Updating JavaScriptObject subclasses 125 | As with most of the deprecated classes kept in this library, existing JavaScriptObject types should be rewritten using 126 | jsinterop annotations to correctly explain to the compiler what is happening. This class can still be convient to use 127 | as an argument or return type, but generally should not be extended in your own projects any longer. 128 | 129 | Some basic guidlines to follow: 130 | * The type itself must be marked as `@JsType(isNative=true)`, most likely with `namespace=JsPackage.GLOBAL`, and 131 | depending on your use case, you might want to always use `name="Object"`, or might want to refer to a different JS 132 | class. 133 | * Existing native methods need to be rewritten either as overlay methods, or made native to describe how they call the 134 | actual JS. A `@JsMethod(name=...)` may be required if the method name is not the same as in JS, or a `@JsProperty` if 135 | the method exists to read/write a property. Fields can also be created - they will be assumed to be named for an 136 | existing JS property, but you can likewise rename them with `@JsProperty`. 137 | * Overlay methods need to be marked with `@JsOverlay`, and continue to need to be effectively final (i.e. never 138 | overridden), but no longer need to be marked as `final`. 139 | 140 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.gwtproject.core 8 | gwt-core-parent 9 | dev 10 | 11 | gwt-core-gwt2-tests 12 | ${revision} 13 | gwt-lib 14 | 15 | GWT Core - GWT 2 Tests 16 | Test cases for the GWT 2 tests 17 | https://github.com/gwtproject/gwt-core 18 | 19 | 20 | The GWT Project Authors 21 | https://github.com/gwtproject 22 | 23 | 24 | 25 | 26 | The Apache Software License, Version 2.0 27 | http://www.apache.org/licenses/LICENSE-2.0.txt 28 | 29 | 30 | 31 | 32 | 33 | The GWT Project Authors 34 | The GWT Project Authors 35 | https://github.com/gwtproject 36 | 37 | 38 | 39 | 40 | scm:git:git://github.com/gwtproject/gwt-core.git 41 | scm:git:ssh://github.com/gwtproject/gwt-core.git 42 | https://github.com/gwtproject/gwt-core/tree/master 43 | 44 | 45 | 2019 46 | 47 | 48 | 1.0.0 49 | 50 | 2.10.0 51 | 52 | 53 | 54 | 55 | com.google.gwt 56 | gwt-user 57 | ${gwt.version} 58 | test 59 | 60 | 61 | com.google.gwt 62 | gwt-dev 63 | ${gwt.version} 64 | test 65 | 66 | 67 | 68 | junit 69 | junit 70 | ${junit.version} 71 | test 72 | 73 | 74 | 75 | org.gwtproject.core 76 | gwt-core 77 | test 78 | 79 | 80 | 81 | 82 | 83 | 84 | net.ltgt.gwt.maven 85 | gwt-maven-plugin 86 | ${maven.gwt.plugin} 87 | true 88 | 89 | true 90 | org.gwtproject.core.CoreSuite 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-deploy-plugin 96 | ${maven.deploy.plugin} 97 | 98 | true 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/CoreSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core; 17 | 18 | import com.google.gwt.junit.tools.GWTTestSuite; 19 | import junit.framework.Test; 20 | import org.gwtproject.core.client.*; 21 | import org.gwtproject.core.client.impl.SchedulerImplTest; 22 | 23 | public class CoreSuite { 24 | 25 | public static Test suite() { 26 | GWTTestSuite suite = new GWTTestSuite("All core tests"); 27 | 28 | suite.addTestSuite(GWTTest.class); 29 | suite.addTestSuite(JavaScriptObjectTest.class); 30 | suite.addTestSuite(JsonUtilsTest.class); 31 | suite.addTestSuite(JsArrayTest.class); 32 | suite.addTestSuite(JsArrayMixedTest.class); 33 | suite.addTestSuite(SchedulerTest.class); 34 | suite.addTestSuite(SchedulerImplTest.class); 35 | suite.addTestSuite(ScriptInjectorTest.class); 36 | 37 | return suite; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/GWTTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Project Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | 20 | public class GWTTest extends GWTTestCase { 21 | @Override 22 | public String getModuleName() { 23 | return "org.gwtproject.core.Core"; 24 | } 25 | 26 | public void testIsScript() { 27 | assertTrue(GWT.isScript()); 28 | assertTrue(org.gwtproject.core.shared.GWT.isScript()); 29 | } 30 | 31 | public void testIsClient() { 32 | assertTrue(GWT.isClient()); 33 | assertTrue(org.gwtproject.core.shared.GWT.isClient()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/JavaScriptObjectTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | 20 | public class JavaScriptObjectTest extends GWTTestCase { 21 | 22 | @Override 23 | public String getModuleName() { 24 | return "org.gwtproject.core.Core"; 25 | } 26 | 27 | public void testJsArray() { 28 | JsArrayString array = JavaScriptObject.createArray(20).cast(); 29 | assertEquals(20, array.length()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/JsArrayMixedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | 20 | /** Tests JsArrayMixed methods. */ 21 | public class JsArrayMixedTest extends GWTTestCase { 22 | 23 | private static class JsTestFruit extends JavaScriptObject { 24 | @SuppressWarnings("unused") 25 | protected JsTestFruit() {} 26 | } 27 | 28 | JsArrayMixed mixedArray; 29 | 30 | @Override 31 | public String getModuleName() { 32 | return "org.gwtproject.core.Core"; 33 | } 34 | 35 | @Override 36 | protected void gwtSetUp() throws Exception { 37 | super.gwtSetUp(); 38 | mixedArray = makeArray(); 39 | } 40 | 41 | public void testGetBoolean() { 42 | assertTrue(mixedArray.getBoolean(0)); 43 | // Test automatic type casting 44 | mixedArray.set(0, 0); 45 | assertFalse(mixedArray.getBoolean(0)); 46 | } 47 | 48 | public void testGetNumber() { 49 | assertEquals(2.5, mixedArray.getNumber(1)); 50 | assertEquals(1.0, mixedArray.getNumber(2)); 51 | // Cast from boolean 52 | assertEquals(1.0, mixedArray.getNumber(0)); 53 | } 54 | 55 | public void testGetObject() { 56 | assertTrue(compareObjects(makeObject("pear"), mixedArray.getObject(3))); 57 | } 58 | 59 | public void testGetString() { 60 | assertEquals("orange", mixedArray.getString(4)); 61 | assertEquals("true", mixedArray.getString(0)); 62 | assertEquals("2.5", mixedArray.getString(1)); 63 | assertEquals("1", mixedArray.getString(2)); 64 | } 65 | 66 | public void testJoin() { 67 | assertEquals("true,2.5,1,[object Object],orange", mixedArray.join()); 68 | } 69 | 70 | public void testJoinString() { 71 | assertEquals("true
2.5
1
[object Object]
orange", mixedArray.join("
")); 72 | } 73 | 74 | public void testLength() { 75 | assertEquals(5, mixedArray.length()); 76 | } 77 | 78 | public void testPushBoolean() { 79 | mixedArray.push(false); 80 | assertEquals(6, mixedArray.length()); 81 | assertFalse(mixedArray.getBoolean(5)); 82 | } 83 | 84 | public void testPushDouble() { 85 | mixedArray.push(1.5); 86 | assertEquals(6, mixedArray.length()); 87 | assertEquals(1.5, mixedArray.getNumber(5)); 88 | } 89 | 90 | public void testPushJavaScriptObject() { 91 | JsTestFruit fruit = makeObject("strawberry"); 92 | mixedArray.push(fruit); 93 | assertEquals(6, mixedArray.length()); 94 | assertEquals(fruit, mixedArray.getObject(5)); 95 | } 96 | 97 | public void testPushString() { 98 | mixedArray.push("kiwi"); 99 | assertEquals(6, mixedArray.length()); 100 | assertEquals("kiwi", mixedArray.getString(5)); 101 | } 102 | 103 | public void testSetIntBoolean() { 104 | mixedArray.set(1, false); 105 | assertFalse(mixedArray.getBoolean(1)); 106 | } 107 | 108 | public void testSetIntDouble() { 109 | mixedArray.set(0, 4.1); 110 | assertEquals(4.1, mixedArray.getNumber(0)); 111 | } 112 | 113 | public void testSetIntJavaScriptObject() { 114 | JsTestFruit fruit = makeObject("kiwi"); 115 | mixedArray.set(0, fruit); 116 | assertEquals(fruit, mixedArray.getObject(0)); 117 | } 118 | 119 | public void testSetIntString() { 120 | mixedArray.set(0, "apple"); 121 | assertEquals("apple", mixedArray.getString(0)); 122 | } 123 | 124 | public void testSetLength() { 125 | mixedArray.setLength(10); 126 | assertEquals(10, mixedArray.length()); 127 | } 128 | 129 | public void testShiftBoolean() { 130 | assertEquals(5, mixedArray.length()); 131 | assertTrue(mixedArray.shiftBoolean()); 132 | assertEquals(4, mixedArray.length()); 133 | assertTrue(mixedArray.shiftBoolean()); 134 | assertTrue(mixedArray.shiftBoolean()); 135 | assertTrue(mixedArray.shiftBoolean()); 136 | assertTrue(mixedArray.shiftBoolean()); 137 | assertEquals(0, mixedArray.length()); 138 | } 139 | 140 | public void testShiftNumber() { 141 | assertEquals(5, mixedArray.length()); 142 | assertEquals(1.0, mixedArray.shiftNumber()); 143 | assertEquals(4, mixedArray.length()); 144 | assertEquals(2.5, mixedArray.shiftNumber()); 145 | assertEquals(1.0, mixedArray.shiftNumber()); 146 | assertTrue(Double.isNaN(mixedArray.shiftNumber())); 147 | assertTrue(Double.isNaN(mixedArray.shiftNumber())); 148 | assertEquals(0, mixedArray.length()); 149 | } 150 | 151 | public void testShiftObject() { 152 | assertEquals(5, mixedArray.length()); 153 | assertEquals("true", mixedArray.shiftObject().toString()); 154 | assertEquals(4, mixedArray.length()); 155 | assertEquals("2.5", mixedArray.shiftObject().toString()); 156 | assertEquals("1", mixedArray.shiftObject().toString()); 157 | assertTrue(compareObjects(makeObject("pear"), mixedArray.shiftObject())); 158 | assertEquals(1, mixedArray.length()); 159 | } 160 | 161 | public void testShiftString() { 162 | assertEquals(5, mixedArray.length()); 163 | assertEquals("true", mixedArray.shiftString()); 164 | assertEquals(4, mixedArray.length()); 165 | assertEquals("2.5", mixedArray.shiftString()); 166 | assertEquals("1", mixedArray.shiftString()); 167 | assertEquals("[object Object]", mixedArray.shiftString()); 168 | assertEquals("orange", mixedArray.shiftString()); 169 | assertEquals(0, mixedArray.length()); 170 | } 171 | 172 | public void testUnshiftBoolean() { 173 | assertEquals(5, mixedArray.length()); 174 | mixedArray.unshift(false); 175 | assertEquals(6, mixedArray.length()); 176 | assertFalse(mixedArray.getBoolean(0)); 177 | } 178 | 179 | public void testUnshiftDouble() { 180 | assertEquals(5, mixedArray.length()); 181 | mixedArray.unshift(0.5); 182 | assertEquals(6, mixedArray.length()); 183 | assertEquals(0.5, mixedArray.getNumber(0)); 184 | } 185 | 186 | public void testUnshiftJavaScriptObject() { 187 | JsTestFruit fruit = makeObject("kiwi"); 188 | assertEquals(5, mixedArray.length()); 189 | mixedArray.unshift(fruit); 190 | assertEquals(6, mixedArray.length()); 191 | assertEquals(fruit, mixedArray.getObject(0)); 192 | } 193 | 194 | public void testUnshiftString() { 195 | assertEquals(5, mixedArray.length()); 196 | mixedArray.unshift("kiwi"); 197 | assertEquals(6, mixedArray.length()); 198 | assertEquals("kiwi", mixedArray.getString(0)); 199 | } 200 | 201 | public void testEdgeCases() { 202 | JsArrayMixed weirdArray = makeEdgeCaseArray(); 203 | 204 | // boolean values 205 | assertFalse(weirdArray.getBoolean(0)); 206 | assertTrue(weirdArray.getBoolean(1)); 207 | assertTrue(weirdArray.getBoolean(2)); 208 | assertTrue(weirdArray.getBoolean(3)); 209 | assertFalse(weirdArray.getBoolean(4)); 210 | assertTrue(weirdArray.getBoolean(5)); 211 | assertFalse(weirdArray.getBoolean(6)); 212 | assertTrue(weirdArray.getBoolean(7)); 213 | assertTrue(weirdArray.getBoolean(8)); 214 | assertTrue(weirdArray.getBoolean(9)); 215 | assertTrue(weirdArray.getBoolean(10)); 216 | 217 | // number values 218 | assertEquals(0.0, weirdArray.getNumber(0)); 219 | assertEquals(0.0, weirdArray.getNumber(1)); 220 | assertEquals(1.0, weirdArray.getNumber(2)); 221 | assertTrue(Double.isNaN(weirdArray.getNumber(3))); 222 | assertEquals(0.0, weirdArray.getNumber(4)); 223 | assertEquals(1.0, weirdArray.getNumber(5)); 224 | assertTrue(Double.isNaN(weirdArray.getNumber(6))); 225 | assertEquals(Double.POSITIVE_INFINITY, weirdArray.getNumber(7)); 226 | assertEquals(0.0, weirdArray.getNumber(8)); 227 | assertEquals(0.0, weirdArray.getNumber(9)); 228 | assertEquals(1.0, weirdArray.getNumber(10)); 229 | 230 | // String values 231 | assertEquals("", weirdArray.getString(0)); 232 | assertEquals("0", weirdArray.getString(1)); 233 | assertEquals("1", weirdArray.getString(2)); 234 | assertEquals("NaN", weirdArray.getString(3)); 235 | assertEquals("0", weirdArray.getString(4)); 236 | assertEquals("1", weirdArray.getString(5)); 237 | assertEquals("NaN", weirdArray.getString(6)); 238 | assertEquals("Infinity", weirdArray.getString(7)); 239 | assertEquals("", weirdArray.getString(8)); 240 | assertEquals("0", weirdArray.getString(9)); 241 | assertEquals("1", weirdArray.getString(10)); 242 | } 243 | 244 | private native boolean compareObjects(JavaScriptObject expected, JavaScriptObject actual) /*-{ 245 | for (key in expected) { 246 | if (expected[key] != actual[key]) { 247 | return false; 248 | } 249 | } 250 | return true; 251 | }-*/; 252 | 253 | private native JsArrayMixed makeArray() /*-{ 254 | return [true, 2.5, 1, {kind: "pear"}, "orange"]; 255 | }-*/; 256 | 257 | private native JsArrayMixed makeEdgeCaseArray() /*-{ 258 | return ['', '0', '1', 'NaN', 0, 1, NaN, Infinity, [], [0], [1]]; 259 | }-*/; 260 | 261 | private native JsTestFruit makeObject(String theKind) /*-{ 262 | return {kind: theKind}; 263 | }-*/; 264 | } 265 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/JsArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | import jsinterop.annotations.JsPackage; 20 | import jsinterop.annotations.JsProperty; 21 | import jsinterop.annotations.JsType; 22 | 23 | /** Tests JsArray variants. */ 24 | public class JsArrayTest extends GWTTestCase { 25 | 26 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 27 | private static class JsPoint extends JavaScriptObject { 28 | protected JsPoint() {} 29 | 30 | @JsProperty(name = "x") 31 | public final native int x(); 32 | 33 | @JsProperty(name = "y") 34 | public final native int y(); 35 | } 36 | 37 | @Override 38 | public String getModuleName() { 39 | return "org.gwtproject.core.Core"; 40 | } 41 | 42 | public void testJsArray() { 43 | // All the test arrays start with 3 elements. 44 | JsArray jsArray = makeJsArray(); 45 | assertEquals(3, jsArray.length()); 46 | 47 | // Get the three points and make sure they are what we think. 48 | JsPoint p0 = jsArray.get(0); 49 | JsPoint p1 = jsArray.get(1); 50 | JsPoint p2 = jsArray.get(2); 51 | 52 | assertEquals("JsPoint,JsPoint,JsPoint", jsArray.join()); 53 | assertEquals("JsPoint:JsPoint:JsPoint", jsArray.join(":")); 54 | 55 | assertEquals(0, p0.x()); 56 | assertEquals(1, p0.y()); 57 | assertEquals(2, p1.x()); 58 | assertEquals(3, p1.y()); 59 | assertEquals(4, p2.x()); 60 | assertEquals(5, p2.y()); 61 | 62 | // Make sure the '3' element is null. 63 | assertNull(jsArray.get(3)); 64 | 65 | // Make a new point and stick it in the '3' slot. It should come back with 66 | // reference equality intact, and the array length should be bumped to 4. 67 | JsPoint p3 = makeJsPoint(6, 7); 68 | jsArray.set(3, p3); 69 | assertEquals(p3, jsArray.get(3)); 70 | assertEquals(4, jsArray.length()); 71 | 72 | jsArray.setLength(0); 73 | assertEquals(0, jsArray.length()); 74 | } 75 | 76 | public void testJsArrayBoolean() { 77 | // All the test arrays start with 3 elements. 78 | JsArrayBoolean jsArray = makeJsArrayBoolean(); 79 | assertEquals(3, jsArray.length()); 80 | 81 | // Get the three points and make sure they are what we think. 82 | assertEquals(true, jsArray.get(0)); 83 | assertEquals(false, jsArray.get(1)); 84 | assertEquals(true, jsArray.get(2)); 85 | 86 | assertEquals("true,false,true", jsArray.join()); 87 | assertEquals("true:false:true", jsArray.join(":")); 88 | 89 | // Stick a new boolean in the '3' slot. It should come back intact, and the 90 | // array length should be bumped to 4. 91 | jsArray.set(3, false); 92 | assertEquals(false, jsArray.get(3)); 93 | assertEquals(4, jsArray.length()); 94 | 95 | // Add another entry (holdover from when this test verified legacy dev mode) 96 | jsArray.set(4, false); 97 | 98 | // Add an element to the beginning of the array 99 | jsArray.unshift(true); 100 | assertEquals(6, jsArray.length()); 101 | assertTrue(jsArray.get(0)); 102 | assertTrue(jsArray.shift()); 103 | assertEquals(5, jsArray.length()); 104 | 105 | jsArray.setLength(0); 106 | assertEquals(0, jsArray.length()); 107 | } 108 | 109 | public void testJsArrayInteger() { 110 | // All the test arrays start with 3 elements. 111 | JsArrayInteger jsArray = makeJsArrayInteger(); 112 | assertEquals(3, jsArray.length()); 113 | 114 | // Get the three points and make sure they are what we think. 115 | assertEquals(0, jsArray.get(0)); 116 | assertEquals(1, jsArray.get(1)); 117 | assertEquals(2, jsArray.get(2)); 118 | 119 | assertEquals("0,1,2", jsArray.join()); 120 | assertEquals("0:1:2", jsArray.join(":")); 121 | 122 | // Stick a new number in the '3' slot. It should come back intact, and the 123 | // array length should be bumped to 4. 124 | jsArray.set(3, 3); 125 | assertEquals(3, jsArray.get(3)); 126 | assertEquals(4, jsArray.length()); 127 | 128 | // Add another entry (holdover from when this test verified legacy dev mode) 129 | jsArray.set(4, 33); 130 | 131 | // Add an element to the beginning of the array 132 | jsArray.unshift(42); 133 | assertEquals(6, jsArray.length()); 134 | assertEquals(42, jsArray.get(0)); 135 | assertEquals(42, jsArray.shift()); 136 | assertEquals(5, jsArray.length()); 137 | 138 | jsArray.setLength(0); 139 | assertEquals(0, jsArray.length()); 140 | } 141 | 142 | public void testJsArrayNumber() { 143 | // All the test arrays start with 3 elements. 144 | JsArrayNumber jsArray = makeJsArrayNumber(); 145 | assertEquals(3, jsArray.length()); 146 | 147 | // Get the three points and make sure they are what we think. 148 | assertEquals(0.0, jsArray.get(0)); 149 | assertEquals(1.1, jsArray.get(1)); 150 | assertEquals(2.2, jsArray.get(2)); 151 | 152 | assertEquals("0,1.1,2.2", jsArray.join()); 153 | assertEquals("0:1.1:2.2", jsArray.join(":")); 154 | 155 | // Stick a new number in the '3' slot. It should come back intact, and the 156 | // array length should be bumped to 4. 157 | jsArray.set(3, 3.0); 158 | assertEquals(3.0, jsArray.get(3)); 159 | assertEquals(4, jsArray.length()); 160 | 161 | // Add another entry (holdover from when this test verified legacy dev mode) 162 | jsArray.set(4, 4.4); 163 | 164 | // Add an element to the beginning of the array 165 | jsArray.unshift(42.0); 166 | assertEquals(6, jsArray.length()); 167 | assertEquals(42.0, jsArray.get(0)); 168 | assertEquals(42.0, jsArray.shift()); 169 | assertEquals(5, jsArray.length()); 170 | 171 | jsArray.setLength(0); 172 | assertEquals(0, jsArray.length()); 173 | } 174 | 175 | public void testJsArrayString() { 176 | // All the test arrays start with 3 elements. 177 | JsArrayString jsArray = makeJsArrayString(); 178 | assertEquals(3, jsArray.length()); 179 | 180 | // Get the three points and make sure they are what we think. 181 | String s0 = jsArray.get(0); 182 | String s1 = jsArray.get(1); 183 | String s2 = jsArray.get(2); 184 | 185 | assertEquals("foo", s0); 186 | assertEquals("bar", s1); 187 | assertEquals("baz", s2); 188 | 189 | assertEquals("foo,bar,baz", jsArray.join()); 190 | assertEquals("foo:bar:baz", jsArray.join(":")); 191 | 192 | // Make sure the '3' element is null. 193 | assertNull(jsArray.get(3)); 194 | 195 | // Stick a new string in the '3' slot. It should come back intact, and the 196 | // array length should be bumped to 4. 197 | jsArray.set(3, "tintin"); 198 | assertEquals("tintin", jsArray.get(3)); 199 | assertEquals(4, jsArray.length()); 200 | 201 | // Add another entry (holdover from when this test verified legacy dev mode) 202 | jsArray.set(4, "quux"); 203 | 204 | // Add an element to the beginning of the array 205 | jsArray.unshift("42"); 206 | assertEquals(6, jsArray.length()); 207 | assertEquals("42", jsArray.get(0)); 208 | assertEquals("42", jsArray.shift()); 209 | assertEquals(5, jsArray.length()); 210 | 211 | jsArray.setLength(0); 212 | assertEquals(0, jsArray.length()); 213 | } 214 | 215 | /** Checks that get, length and set methods work even if the JS object is not actual Array */ 216 | public void testFakeArray() { 217 | JsArray points = makeFakeArray(); 218 | points.set(0, makeJsPoint(1, 2)); 219 | JsPoint pt = points.get(0); 220 | assertEquals(1, pt.x()); 221 | assertEquals(7, points.length()); 222 | } 223 | 224 | private native JsArray makeFakeArray() /*-{ 225 | return {length: 7} 226 | }-*/; 227 | 228 | private native JsArray makeJsArray() /*-{ 229 | return [ 230 | { x: 0, y: 1, toString: function() { return 'JsPoint';} }, 231 | { x: 2, y: 3, toString: function() { return 'JsPoint';} }, 232 | { x: 4, y: 5, toString: function() { return 'JsPoint';} }, 233 | ]; 234 | }-*/; 235 | 236 | private native JsArrayBoolean makeJsArrayBoolean() /*-{ 237 | return [true, false, true]; 238 | }-*/; 239 | 240 | private native JsArrayInteger makeJsArrayInteger() /*-{ 241 | return [0, 1, 2]; 242 | }-*/; 243 | 244 | private native JsArrayNumber makeJsArrayNumber() /*-{ 245 | return [0.0, 1.1, 2.2]; 246 | }-*/; 247 | 248 | private native JsArrayString makeJsArrayString() /*-{ 249 | return ['foo', 'bar', 'baz']; 250 | }-*/; 251 | 252 | private native JsPoint makeJsPoint(int newx, int newy) /*-{ 253 | return {x: newx, y: newy}; 254 | }-*/; 255 | } 256 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/JsonUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | 20 | /** Tests {@link com.google.gwt.core.client.JsonUtils}. */ 21 | public class JsonUtilsTest extends GWTTestCase { 22 | @Override 23 | public String getModuleName() { 24 | return "org.gwtproject.core.Core"; 25 | } 26 | 27 | public void testStringify() throws Exception { 28 | assertEquals("{\"a\":2}", JsonUtils.stringify(createJson())); 29 | assertEquals("{\n\t\"a\": 2\n}", JsonUtils.stringify(createJson(), "\t")); 30 | assertEquals("{\nXYZ\"a\": 2\n}", JsonUtils.stringify(createJson(), "XYZ")); 31 | } 32 | 33 | private native JavaScriptObject createJson() /*-{ 34 | return { a: 2 }; 35 | }-*/; 36 | } 37 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/SchedulerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | import org.gwtproject.core.client.Scheduler.ScheduledCommand; 20 | 21 | public class SchedulerTest extends GWTTestCase { 22 | 23 | private static final int TEST_DELAY = 500000; 24 | 25 | @Override 26 | public String getModuleName() { 27 | return "org.gwtproject.core.Core"; 28 | } 29 | 30 | /** 31 | * Tests that a deferred command can schedule a finally command, which can schedule another 32 | * finally command 33 | */ 34 | public void testEndToEnd() { 35 | final boolean[] ranEntry = {false}; 36 | 37 | final ScheduledCommand finallyCommand = 38 | () -> { 39 | assertTrue(ranEntry[0]); 40 | Scheduler.get().scheduleFinally(() -> finishTest()); 41 | }; 42 | 43 | Scheduler.get() 44 | .scheduleDeferred( 45 | () -> { 46 | ranEntry[0] = true; 47 | Scheduler.get().scheduleFinally(finallyCommand); 48 | }); 49 | 50 | delayTestFinish(TEST_DELAY); 51 | } 52 | 53 | // /** 54 | // * Tests that an entry command can schedule a finally command where the whole 55 | // * thing is kicked off by a deferred command. 56 | // */ 57 | // public void testEndToEndLegacy() { 58 | // final boolean[] ranEntry = {false}; 59 | // 60 | // final ScheduledCommand finallyCommand = new ScheduledCommand() { 61 | // @Override 62 | // public void execute() { 63 | // assertTrue(ranEntry[0]); 64 | // finishTest(); 65 | // } 66 | // }; 67 | // 68 | // Scheduler.get().scheduleEntry(new ScheduledCommand() { 69 | // @Override 70 | // public void execute() { 71 | // ranEntry[0] = true; 72 | // Scheduler.get().scheduleFinally(finallyCommand); 73 | // } 74 | // }); 75 | // 76 | // Scheduler.get().scheduleDeferred(new ScheduledCommand() { 77 | // @Override 78 | // public void execute() { 79 | // assertTrue(ranEntry[0]); 80 | // } 81 | // }); 82 | // 83 | // delayTestFinish(TEST_DELAY); 84 | // } 85 | } 86 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/java/org/gwtproject/core/client/impl/SchedulerImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client.impl; 17 | 18 | import com.google.gwt.junit.client.GWTTestCase; 19 | import elemental2.core.JsArray; 20 | import org.gwtproject.core.client.Duration; 21 | import org.gwtproject.core.client.Scheduler.RepeatingCommand; 22 | import org.gwtproject.core.client.Scheduler.ScheduledCommand; 23 | import org.gwtproject.core.client.impl.SchedulerImpl.Task; 24 | 25 | public class SchedulerImplTest extends GWTTestCase { 26 | 27 | static class ArraySetterCommand implements ScheduledCommand { 28 | private final boolean[] values; 29 | 30 | public ArraySetterCommand(boolean[] values) { 31 | this.values = values; 32 | } 33 | 34 | @Override 35 | public void execute() { 36 | values[0] = true; 37 | } 38 | } 39 | 40 | static class CountingCommand implements RepeatingCommand { 41 | public final int[] values; 42 | 43 | public CountingCommand(int[] values) { 44 | assertEquals(2, values.length); 45 | this.values = values; 46 | } 47 | 48 | @Override 49 | public boolean execute() { 50 | assertTrue("Called too many times", values[0] < values[1]); 51 | values[0] = values[0] + 1; 52 | return values[0] < values[1]; 53 | } 54 | } 55 | 56 | /** A no-op command used to test internal datastructures. */ 57 | static class NullCommand implements ScheduledCommand { 58 | @Override 59 | public void execute() {} 60 | } 61 | 62 | /** 63 | * The EntryCommand and FinallyCommand queues should have the same behavior, so we use this 64 | * interface to reuse the same test logic. 65 | */ 66 | interface QueueTester { 67 | void flush(); 68 | 69 | JsArray queue(); 70 | 71 | void schedule(RepeatingCommand cmd); 72 | 73 | void schedule(ScheduledCommand cmd); 74 | } 75 | 76 | private static class RepeatingCommandImpl implements RepeatingCommand { 77 | private boolean firstTime = true; 78 | private boolean commandRanSecondTime = false; 79 | 80 | @Override 81 | public boolean execute() { 82 | // Command needs to run for the second time to be executed in runScheduledTasks 83 | if (firstTime) { 84 | firstTime = false; 85 | return true; 86 | } 87 | commandRanSecondTime = true; 88 | return false; 89 | } 90 | } 91 | 92 | private static final int TEST_DELAY = 5000; 93 | 94 | @Override 95 | public String getModuleName() { 96 | return "org.gwtproject.core.Core"; 97 | } 98 | 99 | public void testDeferredCommands() { 100 | final SchedulerImpl impl = new SchedulerImpl(); 101 | 102 | final boolean[] values = {false}; 103 | impl.scheduleDeferred(new ArraySetterCommand(values)); 104 | 105 | assertEquals(1, impl.deferredCommands.length); 106 | 107 | ScheduledCommand nullCommand = new NullCommand(); 108 | impl.scheduleDeferred(nullCommand); 109 | assertEquals(2, impl.deferredCommands.length); 110 | assertSame(nullCommand, impl.deferredCommands.getAt(1).getScheduled()); 111 | 112 | impl.scheduleDeferred( 113 | new ScheduledCommand() { 114 | @Override 115 | public void execute() { 116 | assertTrue(values[0]); 117 | assertNull(impl.deferredCommands); 118 | finishTest(); 119 | } 120 | }); 121 | 122 | delayTestFinish(TEST_DELAY); 123 | } 124 | 125 | /** 126 | * This test could potentially timeout since loop in {@link 127 | * org.gwtproject.core.client.impl.SchedulerImpl#runRepeatingTasks} would run indefinitely since 128 | * we are mocking Duration to always return zero. 129 | * 130 | *

see for details: https://code.google.com/p/google-web-toolkit/issues/detail?id=7307 131 | */ 132 | public void testEarlyBreakIfAllTaskAreFinished() { 133 | final SchedulerImpl impl = 134 | new SchedulerImpl() { 135 | @Override 136 | Duration createDuration() { 137 | return new Duration() { 138 | @Override 139 | public int elapsedMillis() { 140 | // never expire 141 | return 0; 142 | } 143 | }; 144 | } 145 | }; 146 | 147 | final RepeatingCommandImpl command = new RepeatingCommandImpl(); 148 | 149 | impl.scheduleIncremental(command); 150 | 151 | impl.scheduleDeferred( 152 | new ScheduledCommand() { 153 | @Override 154 | public void execute() { 155 | 156 | if (command.commandRanSecondTime) { 157 | finishTest(); 158 | } else { 159 | impl.scheduleDeferred(this); 160 | } 161 | } 162 | }); 163 | 164 | delayTestFinish(TEST_DELAY); 165 | } 166 | 167 | // public void testEntryCommands() { 168 | // final SchedulerImpl impl = new SchedulerImpl(); 169 | // 170 | // testQueue(new QueueTester() { 171 | // @Override 172 | // public void flush() { 173 | // impl.flushEntryCommands(); 174 | // } 175 | // 176 | // @Override 177 | // public JsArray queue() { 178 | // return impl.entryCommands; 179 | // } 180 | // 181 | // @Override 182 | // public void schedule(RepeatingCommand cmd) { 183 | // impl.scheduleEntry(cmd); 184 | // } 185 | // 186 | // @Override 187 | // public void schedule(ScheduledCommand cmd) { 188 | // impl.scheduleEntry(cmd); 189 | // } 190 | // }); 191 | // } 192 | 193 | public void testFinallyCommands() { 194 | final SchedulerImpl impl = new SchedulerImpl(); 195 | 196 | testQueue( 197 | new QueueTester() { 198 | @Override 199 | public void flush() { 200 | impl.flushFinallyCommands(); 201 | } 202 | 203 | @Override 204 | public JsArray queue() { 205 | return impl.finallyCommands; 206 | } 207 | 208 | @Override 209 | public void schedule(RepeatingCommand cmd) { 210 | impl.scheduleFinally(cmd); 211 | } 212 | 213 | @Override 214 | public void schedule(ScheduledCommand cmd) { 215 | impl.scheduleFinally(cmd); 216 | } 217 | }); 218 | } 219 | 220 | public void testFixedDelayCommands() { 221 | final SchedulerImpl impl = new SchedulerImpl(); 222 | final int[] values = {0, 4}; 223 | 224 | impl.scheduleFixedDelay(new CountingCommand(values), 20); 225 | // Scheduler doesn't need to maintain state for this kind of command 226 | assertFalse(impl.isWorkQueued()); 227 | 228 | // Busy wait for the counter 229 | impl.scheduleDeferred( 230 | new ScheduledCommand() { 231 | @Override 232 | public void execute() { 233 | if (values[0] == values[1]) { 234 | finishTest(); 235 | } else { 236 | impl.scheduleDeferred(this); 237 | } 238 | } 239 | }); 240 | 241 | delayTestFinish(TEST_DELAY); 242 | } 243 | 244 | public void testFixedPeriodCommands() { 245 | final SchedulerImpl impl = new SchedulerImpl(); 246 | final int[] values = {0, 4}; 247 | 248 | impl.scheduleFixedPeriod(new CountingCommand(values), 20); 249 | // Scheduler doesn't need to maintain state for this kind of command 250 | assertFalse(impl.isWorkQueued()); 251 | 252 | // Busy wait for the counter 253 | impl.scheduleDeferred( 254 | new ScheduledCommand() { 255 | @Override 256 | public void execute() { 257 | if (values[0] == values[1]) { 258 | finishTest(); 259 | } else { 260 | impl.scheduleDeferred(this); 261 | } 262 | } 263 | }); 264 | 265 | delayTestFinish(TEST_DELAY); 266 | } 267 | 268 | public void testIncrementalCommands() { 269 | final SchedulerImpl impl = new SchedulerImpl(); 270 | 271 | final int[] values = {0, 4}; 272 | final CountingCommand counter = new CountingCommand(values); 273 | impl.scheduleIncremental(counter); 274 | 275 | // The first pass is scheduled as a deferred command 276 | assertEquals(1, impl.deferredCommands.length); 277 | 278 | impl.scheduleDeferred( 279 | new ScheduledCommand() { 280 | @Override 281 | public void execute() { 282 | // After the incremental command has fired, it's moved to a new queue 283 | assertNull(impl.deferredCommands); 284 | assertTrue(String.valueOf(values[0]), values[0] <= values[1]); 285 | 286 | if (values[0] == values[1]) { 287 | // Haven't yet cleared the queue, still in flushPostEventPumpCommands 288 | assertNotNull(impl.incrementalCommands); 289 | assertEquals(0, impl.incrementalCommands.length); 290 | finishTest(); 291 | } else { 292 | assertNotNull(impl.incrementalCommands); 293 | assertEquals(1, impl.incrementalCommands.length); 294 | assertSame(counter, impl.incrementalCommands.getAt(0).getRepeating()); 295 | impl.scheduleDeferred(this); 296 | } 297 | } 298 | }); 299 | 300 | assertEquals(2, impl.deferredCommands.length); 301 | 302 | delayTestFinish(TEST_DELAY); 303 | } 304 | 305 | private void testQueue(final QueueTester impl) { 306 | boolean[] oneShotValues = {false}; 307 | final boolean[] chainedValues = {false}; 308 | int[] counterValues = {0, 2}; 309 | 310 | impl.schedule(new ArraySetterCommand(oneShotValues)); 311 | impl.schedule(new CountingCommand(counterValues)); 312 | impl.schedule( 313 | new ScheduledCommand() { 314 | @Override 315 | public void execute() { 316 | // Schedule another entry 317 | impl.schedule(new ArraySetterCommand(chainedValues)); 318 | } 319 | }); 320 | 321 | assertEquals(3, impl.queue().length); 322 | 323 | ScheduledCommand nullCommand = new NullCommand(); 324 | impl.schedule(nullCommand); 325 | assertEquals(4, impl.queue().length); 326 | assertSame(nullCommand, impl.queue().getAt(3).getScheduled()); 327 | 328 | impl.flush(); 329 | 330 | // Ensure the command-schedules-command case has been executed 331 | assertTrue(chainedValues[0]); 332 | 333 | // Test that the RepeatingCommand is still scheduled 334 | assertEquals(1, counterValues[0]); 335 | assertEquals(1, impl.queue().length); 336 | impl.flush(); 337 | 338 | // Everything should be finished now 339 | assertEquals(2, counterValues[0]); 340 | assertTrue(oneShotValues[0]); 341 | assertNull(impl.queue()); 342 | } 343 | } 344 | -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test4.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti4_var__ = 4; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti5_var__ = 5; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test6.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti6_var__ = 6; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test7.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti7_var__ = 7; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_absolute.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __tiabsolute_var__ = 101; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_absolute_top.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __tiabsolutetop_var__ = 102; -------------------------------------------------------------------------------- /gwt-core-gwt2-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_utf8.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti_utf8_var__ = "à"; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.gwtproject.core 8 | gwt-core-parent 9 | dev 10 | 11 | gwt-core-j2cl-tests 12 | ${revision} 13 | 14 | GWT Core - J2CL Tests 15 | Test cases for the J2Cl tests 16 | https://github.com/gwtproject/gwt-core 17 | 18 | 19 | The GWT Project Authors 20 | https://github.com/gwtproject 21 | 22 | 23 | 24 | 25 | The Apache Software License, Version 2.0 26 | http://www.apache.org/licenses/LICENSE-2.0.txt 27 | 28 | 29 | 30 | 31 | 32 | The GWT Project Authors 33 | The GWT Project Authors 34 | https://github.com/gwtproject 35 | 36 | 37 | 38 | 39 | scm:git:git://github.com/gwtproject/gwt-core.git 40 | scm:git:ssh://github.com/gwtproject/gwt-core.git 41 | https://github.com/gwtproject/gwt-core/tree/master 42 | 43 | 44 | 2019 45 | 46 | 47 | 0.20 48 | 3.1.0 49 | 50 | 51 | https://repo.vertispan.com/j2cl/ 52 | 53 | 0.11.0-9336533b6 54 | 55 | 56 | 57 | 58 | 59 | com.vertispan.j2cl 60 | junit-annotations 61 | ${j2cl.version} 62 | test 63 | 64 | 65 | com.vertispan.j2cl 66 | gwttestcase-emul 67 | ${j2cl.version} 68 | test 69 | 70 | 71 | com.vertispan.j2cl 72 | junit-emul 73 | ${j2cl.version} 74 | test 75 | 76 | 77 | 78 | org.gwtproject.core 79 | gwt-core 80 | test 81 | 82 | 83 | 84 | 85 | 86 | 87 | maven-resources-plugin 88 | ${maven.resource.plugin} 89 | 90 | 91 | 92 | copy-resources 93 | generate-test-resources 94 | 95 | copy-resources 96 | 97 | 98 | UTF-8 99 | ${project.build.directory}/${project.artifactId}-${project.version}-test/${project.artifactId}/ 100 | 101 | 102 | src/test/resources/org/gwtproject/core/public 103 | false 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | com.vertispan.j2cl 112 | j2cl-maven-plugin 113 | ${maven.j2cl.plugin} 114 | 115 | 116 | ADVANCED 117 | 118 | 119 | 120 | j2cl-test 121 | test 122 | 123 | test 124 | 125 | 126 | 127 | 128 | 129 | org.apache.maven.plugins 130 | maven-surefire-plugin 131 | ${maven.surfire.plugin} 132 | 133 | true 134 | 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-deploy-plugin 139 | ${maven.deploy.plugin} 140 | 141 | true 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | vertispan-snapshots 150 | Vertispan hosted artifacts-releases 151 | ${vertispan.j2cl.repo.url} 152 | 153 | 154 | 155 | 156 | 157 | vertispan-releases 158 | Vertispan hosted artifacts-releases 159 | ${vertispan.j2cl.repo.url} 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/GWTTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Project Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.assertTrue; 19 | 20 | import com.google.j2cl.junit.apt.J2clTestInput; 21 | import org.junit.Test; 22 | 23 | @J2clTestInput(GWTTest.class) 24 | public class GWTTest { 25 | 26 | @Test 27 | public void testIsScript() { 28 | assertTrue(GWT.isScript()); 29 | assertTrue(org.gwtproject.core.shared.GWT.isScript()); 30 | } 31 | 32 | @Test 33 | public void testIsClient() { 34 | assertTrue(GWT.isClient()); 35 | assertTrue(org.gwtproject.core.shared.GWT.isClient()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/JavaScriptObjectTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.assertEquals; 19 | 20 | import com.google.j2cl.junit.apt.J2clTestInput; 21 | import org.junit.Test; 22 | 23 | @J2clTestInput(JavaScriptObjectTest.class) 24 | public class JavaScriptObjectTest { 25 | 26 | @Test 27 | public void testJsArray() { 28 | JsArrayString array = JavaScriptObject.createArray(20).cast(); 29 | assertEquals(20, array.length()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/JsArrayMixedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.*; 19 | 20 | import com.google.j2cl.junit.apt.J2clTestInput; 21 | import elemental2.core.Global; 22 | import elemental2.core.JsArray; 23 | import jsinterop.annotations.JsPackage; 24 | import jsinterop.annotations.JsType; 25 | import jsinterop.base.Js; 26 | import jsinterop.base.JsPropertyMap; 27 | import org.junit.Test; 28 | 29 | /** Tests JsArrayMixed methods. */ 30 | @J2clTestInput(JsArrayMixedTest.class) 31 | public class JsArrayMixedTest { 32 | 33 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 34 | private static class JsTestFruit extends JavaScriptObject { 35 | @SuppressWarnings("unused") 36 | protected JsTestFruit() {} 37 | } 38 | 39 | { 40 | mixedArray = makeArray(); 41 | } 42 | 43 | JsArrayMixed mixedArray; 44 | 45 | @Test 46 | public void testGetBoolean() { 47 | assertTrue(mixedArray.getBoolean(0)); 48 | // Test automatic type casting 49 | mixedArray.set(0, 0); 50 | assertFalse(mixedArray.getBoolean(0)); 51 | } 52 | 53 | @Test 54 | public void testGetNumber() { 55 | assertEquals(2.5, mixedArray.getNumber(1), 0); 56 | assertEquals(1.0, mixedArray.getNumber(2), 0); 57 | // Cast from boolean 58 | assertEquals(1.0, mixedArray.getNumber(0), 0); 59 | } 60 | 61 | @Test 62 | public void testGetObject() { 63 | assertTrue(compareObjects(makeObject("pear"), mixedArray.getObject(3))); 64 | } 65 | 66 | @Test 67 | public void testGetString() { 68 | assertEquals("orange", mixedArray.getString(4)); 69 | assertEquals("true", mixedArray.getString(0)); 70 | assertEquals("2.5", mixedArray.getString(1)); 71 | assertEquals("1", mixedArray.getString(2)); 72 | } 73 | 74 | @Test 75 | public void testJoin() { 76 | assertEquals("true,2.5,1,[object Object],orange", mixedArray.join()); 77 | } 78 | 79 | @Test 80 | public void testJoinString() { 81 | assertEquals("true
2.5
1
[object Object]
orange", mixedArray.join("
")); 82 | } 83 | 84 | @Test 85 | public void testLength() { 86 | assertEquals(5, mixedArray.length()); 87 | } 88 | 89 | @Test 90 | public void testPushBoolean() { 91 | mixedArray.push(false); 92 | assertEquals(6, mixedArray.length()); 93 | assertFalse(mixedArray.getBoolean(5)); 94 | } 95 | 96 | @Test 97 | public void testPushDouble() { 98 | mixedArray.push(1.5); 99 | assertEquals(6, mixedArray.length()); 100 | assertEquals(1.5, mixedArray.getNumber(5), 0); 101 | } 102 | 103 | @Test 104 | public void testPushJavaScriptObject() { 105 | JsTestFruit fruit = makeObject("strawberry"); 106 | mixedArray.push(fruit); 107 | assertEquals(6, mixedArray.length()); 108 | assertEquals(fruit, mixedArray.getObject(5)); 109 | } 110 | 111 | @Test 112 | public void testPushString() { 113 | mixedArray.push("kiwi"); 114 | assertEquals(6, mixedArray.length()); 115 | assertEquals("kiwi", mixedArray.getString(5)); 116 | } 117 | 118 | @Test 119 | public void testSetIntBoolean() { 120 | mixedArray.set(1, false); 121 | assertFalse(mixedArray.getBoolean(1)); 122 | } 123 | 124 | @Test 125 | public void testSetIntDouble() { 126 | mixedArray.set(0, 4.1); 127 | assertEquals(4.1, mixedArray.getNumber(0), 0); 128 | } 129 | 130 | @Test 131 | public void testSetIntJavaScriptObject() { 132 | JsTestFruit fruit = makeObject("kiwi"); 133 | mixedArray.set(0, fruit); 134 | assertEquals(fruit, mixedArray.getObject(0)); 135 | } 136 | 137 | @Test 138 | public void testSetIntString() { 139 | mixedArray.set(0, "apple"); 140 | assertEquals("apple", mixedArray.getString(0)); 141 | } 142 | 143 | @Test 144 | public void testSetLength() { 145 | mixedArray.setLength(10); 146 | assertEquals(10, mixedArray.length()); 147 | } 148 | 149 | @Test 150 | public void testShiftBoolean() { 151 | assertEquals(5, mixedArray.length()); 152 | assertTrue(mixedArray.shiftBoolean()); 153 | assertEquals(4, mixedArray.length()); 154 | assertTrue(mixedArray.shiftBoolean()); 155 | assertTrue(mixedArray.shiftBoolean()); 156 | assertTrue(mixedArray.shiftBoolean()); 157 | assertTrue(mixedArray.shiftBoolean()); 158 | assertEquals(0, mixedArray.length()); 159 | } 160 | 161 | @Test 162 | public void testShiftNumber() { 163 | assertEquals(5, mixedArray.length()); 164 | assertEquals(1.0, mixedArray.shiftNumber(), 0); 165 | assertEquals(4, mixedArray.length()); 166 | assertEquals(2.5, mixedArray.shiftNumber(), 0); 167 | assertEquals(1.0, mixedArray.shiftNumber(), 0); 168 | assertTrue(Double.isNaN(mixedArray.shiftNumber())); 169 | assertTrue(Double.isNaN(mixedArray.shiftNumber())); 170 | assertEquals(0, mixedArray.length()); 171 | } 172 | 173 | @Test 174 | public void testShiftObject() { 175 | assertEquals(5, mixedArray.length()); 176 | assertEquals("true", mixedArray.shiftObject().toString()); 177 | assertEquals(4, mixedArray.length()); 178 | assertEquals("2.5", mixedArray.shiftObject().toString()); 179 | assertEquals("1", mixedArray.shiftObject().toString()); 180 | assertTrue(compareObjects(makeObject("pear"), mixedArray.shiftObject())); 181 | assertEquals(1, mixedArray.length()); 182 | } 183 | 184 | @Test 185 | public void testShiftString() { 186 | assertEquals(5, mixedArray.length()); 187 | assertEquals("true", mixedArray.shiftString()); 188 | assertEquals(4, mixedArray.length()); 189 | assertEquals("2.5", mixedArray.shiftString()); 190 | assertEquals("1", mixedArray.shiftString()); 191 | assertEquals("[object Object]", mixedArray.shiftString()); 192 | assertEquals("orange", mixedArray.shiftString()); 193 | assertEquals(0, mixedArray.length()); 194 | } 195 | 196 | @Test 197 | public void testUnshiftBoolean() { 198 | assertEquals(5, mixedArray.length()); 199 | mixedArray.unshift(false); 200 | assertEquals(6, mixedArray.length()); 201 | assertFalse(mixedArray.getBoolean(0)); 202 | } 203 | 204 | @Test 205 | public void testUnshiftDouble() { 206 | assertEquals(5, mixedArray.length()); 207 | mixedArray.unshift(0.5); 208 | assertEquals(6, mixedArray.length()); 209 | assertEquals(0.5, mixedArray.getNumber(0), 0); 210 | } 211 | 212 | @Test 213 | public void testUnshiftJavaScriptObject() { 214 | JsTestFruit fruit = makeObject("kiwi"); 215 | assertEquals(5, mixedArray.length()); 216 | mixedArray.unshift(fruit); 217 | assertEquals(6, mixedArray.length()); 218 | assertEquals(fruit, mixedArray.getObject(0)); 219 | } 220 | 221 | @Test 222 | public void testUnshiftString() { 223 | assertEquals(5, mixedArray.length()); 224 | mixedArray.unshift("kiwi"); 225 | assertEquals(6, mixedArray.length()); 226 | assertEquals("kiwi", mixedArray.getString(0)); 227 | } 228 | 229 | @Test 230 | public void testEdgeCases() { 231 | JsArrayMixed weirdArray = makeEdgeCaseArray(); 232 | 233 | // boolean values 234 | assertFalse(weirdArray.getBoolean(0)); 235 | assertTrue(weirdArray.getBoolean(1)); 236 | assertTrue(weirdArray.getBoolean(2)); 237 | assertTrue(weirdArray.getBoolean(3)); 238 | assertFalse(weirdArray.getBoolean(4)); 239 | assertTrue(weirdArray.getBoolean(5)); 240 | assertFalse(weirdArray.getBoolean(6)); 241 | assertTrue(weirdArray.getBoolean(7)); 242 | assertTrue(weirdArray.getBoolean(8)); 243 | assertTrue(weirdArray.getBoolean(9)); 244 | assertTrue(weirdArray.getBoolean(10)); 245 | 246 | // number values 247 | assertEquals(0.0, weirdArray.getNumber(0), 0); 248 | assertEquals(0.0, weirdArray.getNumber(1), 0); 249 | assertEquals(1.0, weirdArray.getNumber(2), 0); 250 | assertTrue(Double.isNaN(weirdArray.getNumber(3))); 251 | assertEquals(0.0, weirdArray.getNumber(4), 0); 252 | assertEquals(1.0, weirdArray.getNumber(5), 0); 253 | assertTrue(Double.isNaN(weirdArray.getNumber(6))); 254 | assertEquals(Double.POSITIVE_INFINITY, weirdArray.getNumber(7), 0); 255 | assertEquals(0.0, weirdArray.getNumber(8), 0); 256 | assertEquals(0.0, weirdArray.getNumber(9), 0); 257 | assertEquals(1.0, weirdArray.getNumber(10), 0); 258 | 259 | // TODO: arrary.toString() will return Object.toString() instead of a normal 260 | // String as expeced in JS. J2CL handels it in a different way, than 261 | // GWT does. Atm we will not fix this behavior. 262 | // DomGlobal.console.log("0 -> " + weirdArray.getString(0)); 263 | // DomGlobal.console.log("1 -> " + weirdArray.getString(1)); 264 | // DomGlobal.console.log("2 -> " + weirdArray.getString(2)); 265 | // DomGlobal.console.log("3 -> " + weirdArray.getString(3)); 266 | // DomGlobal.console.log("4 -> " + weirdArray.getString(4)); 267 | // DomGlobal.console.log("5 -> " + weirdArray.getString(5)); 268 | // DomGlobal.console.log("6 -> " + weirdArray.getString(6)); 269 | // DomGlobal.console.log("7 -> " + weirdArray.getString(7)); 270 | // DomGlobal.console.log("8 -> " + weirdArray.getString(8)); 271 | // DomGlobal.console.log("9 -> " + weirdArray.getString(9)); 272 | // DomGlobal.console.log("10 -> " + weirdArray.getString(10)); 273 | // // String values 274 | // assertEquals("", weirdArray.getString(0)); 275 | // assertEquals("0", weirdArray.getString(1)); 276 | // assertEquals("1", weirdArray.getString(2)); 277 | // assertEquals("NaN", weirdArray.getString(3)); 278 | // assertEquals("0", weirdArray.getString(4)); 279 | // assertEquals("1", weirdArray.getString(5)); 280 | // assertEquals("NaN", weirdArray.getString(6)); 281 | // assertEquals("Infinity", weirdArray.getString(7)); 282 | // assertEquals("", weirdArray.getString(8)); 283 | // assertEquals("0", weirdArray.getString(9)); 284 | // assertEquals("1", weirdArray.getString(10)); 285 | } 286 | 287 | private boolean compareObjects(JavaScriptObject expected, JavaScriptObject actual) { 288 | final boolean[] equals = {true}; 289 | Js.asPropertyMap(expected) 290 | .forEach( 291 | key -> { 292 | if (!Js.asPropertyMap(expected).get(key).equals(Js.asPropertyMap(actual).get(key))) { 293 | if (equals[0]) { 294 | equals[0] = false; 295 | return; 296 | } 297 | } 298 | }); 299 | return equals[0]; 300 | } 301 | 302 | private JsArrayMixed makeArray() { 303 | return Js.cast( 304 | elemental2.core.JsArray.of(true, 2.5, 1, JsPropertyMap.of("kind", "pear"), "orange")); 305 | } 306 | 307 | private JsArrayMixed makeEdgeCaseArray() { 308 | return Js.cast( 309 | elemental2.core.JsArray.of( 310 | "", 311 | "0", 312 | "1", 313 | "NaN", 314 | Js.asAny(0), 315 | Js.asAny(1), 316 | Global.NaN, 317 | Global.Infinity, 318 | new JsArray<>(), 319 | new JsArray<>(0), 320 | new JsArray<>(1))); 321 | } 322 | 323 | // private native JsArrayMixed makeEdgeCaseArray() /*-{ 324 | // return ['', '0', '1', 'NaN', 0, 1, NaN, Infinity, [], [0], [1]]; 325 | // }-*/; 326 | 327 | private JsTestFruit makeObject(String theKind) { 328 | return Js.cast(JsPropertyMap.of("kind", theKind)); 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/JsArrayTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.*; 19 | 20 | import com.google.j2cl.junit.apt.J2clTestInput; 21 | import jsinterop.annotations.JsFunction; 22 | import jsinterop.annotations.JsPackage; 23 | import jsinterop.annotations.JsProperty; 24 | import jsinterop.annotations.JsType; 25 | import jsinterop.base.Js; 26 | import jsinterop.base.JsPropertyMap; 27 | import org.junit.Test; 28 | 29 | /** Tests JsArray variants. */ 30 | @J2clTestInput(JsArrayTest.class) 31 | public class JsArrayTest { 32 | 33 | @FunctionalInterface 34 | @JsFunction 35 | public interface ToString { 36 | 37 | public String getString(); 38 | } 39 | 40 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 41 | private static class JsPoint extends JavaScriptObject { 42 | protected JsPoint() {} 43 | 44 | @JsProperty(name = "x") 45 | public final native int x(); 46 | 47 | @JsProperty(name = "y") 48 | public final native int y(); 49 | } 50 | 51 | @Test 52 | public void testJsArray() { 53 | // All the test arrays start with 3 elements. 54 | JsArray jsArray = makeJsArray(); 55 | assertEquals(3, jsArray.length()); 56 | 57 | // Get the three points and make sure they are what we think. 58 | JsPoint p0 = jsArray.get(0); 59 | JsPoint p1 = jsArray.get(1); 60 | JsPoint p2 = jsArray.get(2); 61 | 62 | assertEquals("JsPoint,JsPoint,JsPoint", jsArray.join()); 63 | assertEquals("JsPoint,JsPoint,JsPoint", jsArray.join()); 64 | assertEquals("JsPoint:JsPoint:JsPoint", jsArray.join(":")); 65 | 66 | assertEquals(0, p0.x()); 67 | assertEquals(1, p0.y()); 68 | assertEquals(2, p1.x()); 69 | assertEquals(3, p1.y()); 70 | assertEquals(4, p2.x()); 71 | assertEquals(5, p2.y()); 72 | 73 | // Make sure the '3' element is null. 74 | assertNull(jsArray.get(3)); 75 | 76 | // Make a new point and stick it in the '3' slot. It should come back with 77 | // reference equality intact, and the array length should be bumped to 4. 78 | JsPoint p3 = makeJsPoint(6, 7); 79 | jsArray.set(3, p3); 80 | assertEquals(p3, jsArray.get(3)); 81 | assertEquals(4, jsArray.length()); 82 | 83 | jsArray.setLength(0); 84 | assertEquals(0, jsArray.length()); 85 | } 86 | 87 | @Test 88 | public void testJsArrayBoolean() { 89 | // All the test arrays start with 3 elements. 90 | JsArrayBoolean jsArray = makeJsArrayBoolean(); 91 | assertEquals(3, jsArray.length()); 92 | 93 | // Get the three points and make sure they are what we think. 94 | assertEquals(true, jsArray.get(0)); 95 | assertEquals(false, jsArray.get(1)); 96 | assertEquals(true, jsArray.get(2)); 97 | 98 | assertEquals("true,false,true", jsArray.join()); 99 | assertEquals("true:false:true", jsArray.join(":")); 100 | 101 | // Stick a new boolean in the '3' slot. It should come back intact, and the 102 | // array length should be bumped to 4. 103 | jsArray.set(3, false); 104 | assertEquals(false, jsArray.get(3)); 105 | assertEquals(4, jsArray.length()); 106 | 107 | // Stick a non-boolean value in the '4' slot. Getting it should cause a type 108 | // error in Development Mode. 109 | // Keep the length of the array sane for the remainer of the test 110 | jsArray.set(4, false); 111 | 112 | // Add an element to the beginning of the array 113 | jsArray.unshift(true); 114 | assertEquals(6, jsArray.length()); 115 | assertTrue(jsArray.get(0)); 116 | assertTrue(jsArray.shift()); 117 | assertEquals(5, jsArray.length()); 118 | 119 | jsArray.setLength(0); 120 | assertEquals(0, jsArray.length()); 121 | } 122 | 123 | @Test 124 | public void testJsArrayInteger() { 125 | // All the test arrays start with 3 elements. 126 | JsArrayInteger jsArray = makeJsArrayInteger(); 127 | assertEquals(3, jsArray.length()); 128 | 129 | // Get the three points and make sure they are what we think. 130 | assertEquals(0, jsArray.get(0)); 131 | assertEquals(1, jsArray.get(1)); 132 | assertEquals(2, jsArray.get(2)); 133 | 134 | assertEquals("0,1,2", jsArray.join()); 135 | assertEquals("0:1:2", jsArray.join(":")); 136 | 137 | // Stick a new number in the '3' slot. It should come back intact, and the 138 | // array length should be bumped to 4. 139 | jsArray.set(3, 3); 140 | assertEquals(3, jsArray.get(3)); 141 | assertEquals(4, jsArray.length()); 142 | 143 | // Stick a non-numeric value in the '4' slot. Getting it should cause a type 144 | // error in Development Mode. 145 | // Keep the length of the array sane for the remainer of the test 146 | jsArray.set(4, 33); 147 | 148 | // Add an element to the beginning of the array 149 | jsArray.unshift(42); 150 | assertEquals(6, jsArray.length()); 151 | assertEquals(42, jsArray.get(0)); 152 | assertEquals(42, jsArray.shift()); 153 | assertEquals(5, jsArray.length()); 154 | 155 | jsArray.setLength(0); 156 | assertEquals(0, jsArray.length()); 157 | } 158 | 159 | @Test 160 | public void testJsArrayNumber() { 161 | // All the test arrays start with 3 elements. 162 | JsArrayNumber jsArray = makeJsArrayNumber(); 163 | assertEquals(3, jsArray.length()); 164 | 165 | // Get the three points and make sure they are what we think. 166 | assertEquals(0.0, jsArray.get(0), 0); 167 | assertEquals(1.1, jsArray.get(1), 0); 168 | assertEquals(2.2, jsArray.get(2), 0); 169 | 170 | assertEquals("0,1.1,2.2", jsArray.join()); 171 | assertEquals("0:1.1:2.2", jsArray.join(":")); 172 | 173 | // Stick a new number in the '3' slot. It should come back intact, and the 174 | // array length should be bumped to 4. 175 | jsArray.set(3, 3.0); 176 | assertEquals(3.0, jsArray.get(3), 0); 177 | assertEquals(4, jsArray.length()); 178 | 179 | // Stick a non-numeric value in the '4' slot. Getting it should cause a type 180 | // error in Development Mode. 181 | // Keep the length of the array sane for the remainer of the test 182 | jsArray.set(4, 4.4); 183 | 184 | // Add an element to the beginning of the array 185 | jsArray.unshift(42.0); 186 | assertEquals(6, jsArray.length()); 187 | assertEquals(42.0, jsArray.get(0), 0); 188 | assertEquals(42.0, jsArray.shift(), 0); 189 | assertEquals(5, jsArray.length()); 190 | 191 | jsArray.setLength(0); 192 | assertEquals(0, jsArray.length()); 193 | } 194 | 195 | @Test 196 | public void testJsArrayString() { 197 | // All the test arrays start with 3 elements. 198 | JsArrayString jsArray = makeJsArrayString(); 199 | assertEquals(3, jsArray.length()); 200 | 201 | // Get the three points and make sure they are what we think. 202 | String s0 = jsArray.get(0); 203 | String s1 = jsArray.get(1); 204 | String s2 = jsArray.get(2); 205 | 206 | assertEquals("foo", s0); 207 | assertEquals("bar", s1); 208 | assertEquals("baz", s2); 209 | 210 | assertEquals("foo,bar,baz", jsArray.join()); 211 | assertEquals("foo:bar:baz", jsArray.join(":")); 212 | 213 | // Make sure the '3' element is null. 214 | assertNull(jsArray.get(3)); 215 | 216 | // Stick a new string in the '3' slot. It should come back intact, and the 217 | // array length should be bumped to 4. 218 | jsArray.set(3, "tintin"); 219 | assertEquals("tintin", jsArray.get(3)); 220 | assertEquals(4, jsArray.length()); 221 | 222 | jsArray.set(4, "quux"); 223 | 224 | // Add an element to the beginning of the array 225 | jsArray.unshift("42"); 226 | assertEquals(6, jsArray.length()); 227 | assertEquals("42", jsArray.get(0)); 228 | assertEquals("42", jsArray.shift()); 229 | assertEquals(5, jsArray.length()); 230 | 231 | jsArray.setLength(0); 232 | assertEquals(0, jsArray.length()); 233 | } 234 | 235 | private JsArray makeJsArray() { 236 | return Js.cast( 237 | elemental2.core.JsArray.of(makeJsPoint(0, 1), makeJsPoint(2, 3), makeJsPoint(4, 5))); 238 | } 239 | 240 | private JsArrayBoolean makeJsArrayBoolean() { 241 | return Js.cast(elemental2.core.JsArray.of(true, false, true)); 242 | } 243 | 244 | private JsArrayInteger makeJsArrayInteger() { 245 | return Js.cast(elemental2.core.JsArray.of(0.d, 1.d, 2.d)); 246 | } 247 | 248 | private JsArrayNumber makeJsArrayNumber() { 249 | return Js.cast(elemental2.core.JsArray.of(0.0, 1.1, 2.2)); 250 | } 251 | 252 | private JsArrayString makeJsArrayString() { 253 | return Js.cast(elemental2.core.JsArray.of("foo", "bar", "baz")); 254 | } 255 | 256 | private JsPoint makeJsPoint(int newx, int newy) { 257 | return Js.cast( 258 | JsPropertyMap.of( 259 | "x", 260 | newx, 261 | "y", 262 | newy, 263 | "toString", 264 | (org.gwtproject.core.client.JsArrayTest.ToString) () -> "JsPoint")); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/JsonUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.assertEquals; 19 | 20 | import com.google.j2cl.junit.apt.J2clTestInput; 21 | import elemental2.core.Global; 22 | import jsinterop.base.Js; 23 | import org.junit.Test; 24 | 25 | @J2clTestInput(JsonUtilsTest.class) 26 | public class JsonUtilsTest { 27 | 28 | @Test 29 | public void testStringify() { 30 | assertEquals("{\"a\":2}", JsonUtils.stringify(createJson())); 31 | assertEquals("{\n\t\"a\": 2\n}", JsonUtils.stringify(createJson(), "\t")); 32 | assertEquals("{\nXYZ\"a\": 2\n}", JsonUtils.stringify(createJson(), "XYZ")); 33 | } 34 | 35 | private JavaScriptObject createJson() { 36 | return Js.cast(Global.JSON.parse("{ \"a\": 2 }")); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/java/org/gwtproject/core/client/SchedulerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2020 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static org.junit.Assert.assertFalse; 19 | import static org.junit.Assert.assertTrue; 20 | 21 | import com.google.j2cl.junit.apt.J2clTestInput; 22 | import elemental2.promise.Promise; 23 | import org.gwtproject.core.client.Scheduler.ScheduledCommand; 24 | import org.junit.Test; 25 | 26 | @J2clTestInput(SchedulerTest.class) 27 | public class SchedulerTest { 28 | 29 | private static final int TEST_DELAY = 10000; 30 | 31 | @Test(timeout = TEST_DELAY) 32 | public Promise testEndToEnd() { 33 | 34 | return new Promise( 35 | (resolve, reject) -> { 36 | final boolean[] ranDeferred = {false}; 37 | final boolean[] ranFinally = {false}; 38 | 39 | final ScheduledCommand finallyCommand = 40 | () -> { 41 | assertTrue(ranDeferred[0]); 42 | assertFalse(ranFinally[0]); 43 | ranFinally[0] = true; 44 | 45 | Scheduler.get() 46 | .scheduleFinally( 47 | new ScheduledCommand() { 48 | 49 | @Override 50 | public void execute() { 51 | assertTrue(ranFinally[0]); 52 | resolve.onInvoke((Void) null); 53 | } 54 | }); 55 | }; 56 | 57 | Scheduler.get() 58 | .scheduleDeferred( 59 | () -> { 60 | ranDeferred[0] = true; 61 | Scheduler.get().scheduleFinally(finallyCommand); 62 | }); 63 | }); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test4.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti4_var__ = 4; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti5_var__ = 5; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test6.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti6_var__ = 6; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test7.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti7_var__ = 7; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_absolute.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __tiabsolute_var__ = 101; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_absolute_top.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __tiabsolutetop_var__ = 102; -------------------------------------------------------------------------------- /gwt-core-j2cl-tests/src/test/resources/org/gwtproject/core/public/script_injector_test_utf8.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | __ti_utf8_var__ = "à"; -------------------------------------------------------------------------------- /gwt-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.gwtproject.core 7 | gwt-core-parent 8 | dev 9 | 10 | gwt-core 11 | ${revision} 12 | gwt-lib 13 | 14 | GWT Core 15 | GWT Core 16 | https://github.com/gwtproject/gwt-core 17 | 18 | The GWT Project Authors 19 | https://github.com/gwtproject 20 | 21 | 22 | 23 | 24 | The Apache Software License, Version 2.0 25 | http://www.apache.org/licenses/LICENSE-2.0.txt 26 | 27 | 28 | 29 | 30 | 31 | The GWT Project Authors 32 | The GWT Project Authors 33 | https://github.com/gwtproject 34 | 35 | 36 | 37 | 38 | scm:git:git://github.com/gwtproject/gwt-core.git 39 | scm:git:ssh://github.com/gwtproject/gwt-core.git 40 | https://github.com/gwtproject/gwt-core/tree/master 41 | 42 | 43 | 2019 44 | 45 | 46 | 1.0.0 47 | 1.6 48 | 3.2.0 49 | 3.2.1 50 | 51 | 52 | 53 | 54 | com.google.elemental2 55 | elemental2-core 56 | ${elemental2.version} 57 | 58 | 59 | com.google.elemental2 60 | elemental2-dom 61 | ${elemental2.version} 62 | 63 | 64 | 65 | junit 66 | junit 67 | ${junit.version} 68 | test 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.apache.maven.plugins 76 | maven-surefire-plugin 77 | ${maven.surfire.plugin} 78 | 79 | 80 | test 81 | 82 | test 83 | 84 | 85 | 86 | 87 | 88 | net.ltgt.gwt.maven 89 | gwt-maven-plugin 90 | ${maven.gwt.plugin} 91 | true 92 | 93 | org.gwtproject.core.Core 94 | 95 | 96 | 97 | org.apache.maven.plugins 98 | maven-deploy-plugin 99 | ${maven.deploy.plugin} 100 | 101 | false 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | release 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-source-plugin 116 | ${maven.source.plugin} 117 | 118 | 119 | attach-sources 120 | 121 | jar-no-fork 122 | 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-javadoc-plugin 129 | ${maven.javadoc.plugin} 130 | 131 | 132 | attach-javadocs 133 | 134 | jar 135 | 136 | 137 | 138 | 139 | 140 | 141 | org.apache.maven.plugins 142 | maven-gpg-plugin 143 | ${maven.gpg.plugin} 144 | 145 | 146 | sign-artifacts 147 | verify 148 | 149 | sign 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/Callback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | /** 19 | * A callback for any asynchronous call that can result in success or failure. 20 | * 21 | * @param The type returned on success 22 | * @param The type returned on failure 23 | */ 24 | public interface Callback { 25 | 26 | /** 27 | * Called when an asynchronous call fails to complete normally. 28 | * 29 | * @param reason failure encountered 30 | */ 31 | void onFailure(F reason); 32 | 33 | /** 34 | * Called when an asynchronous call completes successfully. 35 | * 36 | * @param result the value returned 37 | */ 38 | void onSuccess(T result); 39 | } 40 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/Duration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.JsDate; 19 | import jsinterop.base.Js; 20 | 21 | public class Duration { 22 | 23 | /** 24 | * Returns the same result as {@link System#currentTimeMillis()}, but as a double. Because 25 | * emulated long math is significantly slower than doubles in Production Mode, this method is to 26 | * be preferred. 27 | * 28 | * @return current time in millis as double 29 | */ 30 | public static double currentTimeMillis() { 31 | return JsDate.now(); 32 | } 33 | 34 | private double start = currentTimeMillis(); 35 | 36 | /** Creates a new Duration whose start time is now. */ 37 | public Duration() {} 38 | 39 | /** 40 | * returns the number of milliseconds that have elapsed since this object was created. 41 | * 42 | * @return milliseconds 43 | */ 44 | public int elapsedMillis() { 45 | return Js.coerceToInt(currentTimeMillis() - start); 46 | } 47 | 48 | /** 49 | * Returns the time when the object was created. 50 | * 51 | * @return creation time 52 | */ 53 | public double getStartMillis() { 54 | return start; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/GWT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.dom.DomGlobal; 19 | import elemental2.dom.Window; 20 | import jsinterop.annotations.JsMethod; 21 | import jsinterop.annotations.JsType; 22 | import jsinterop.base.Js; 23 | 24 | /** 25 | * Supports core functionality that in some cases requires direct support from the compiler and 26 | * runtime systems such as runtime type information and deferred binding. 27 | */ 28 | public final class GWT { 29 | 30 | /** 31 | * This interface is used to catch exceptions at the "top level" just before they escape to the 32 | * browser. This is used in places where the browser calls into user code such as event callbacks, 33 | * timers, and RPC. 34 | * 35 | *

In Development Mode, the default handler prints a stack trace to the log window. In 36 | * Production Mode, the default handler is null and thus exceptions are allowed to escape, which 37 | * provides an opportunity to use a JavaScript debugger. 38 | */ 39 | public interface UncaughtExceptionHandler { 40 | void onUncaughtException(Throwable e); 41 | } 42 | 43 | private static UncaughtExceptionHandler uncaughtExceptionHandler = null; 44 | private static boolean onErrorInitialized; 45 | 46 | @Deprecated 47 | public static T create(Class clazz) { 48 | return org.gwtproject.core.shared.GWT.create(clazz); 49 | } 50 | 51 | /** 52 | * Throws an exception so that it is handled by the browser, but doesn't interrupt the execution 53 | * of this iteration of the event loop. 54 | * 55 | * @param e the exception to report to the browser 56 | */ 57 | @Deprecated 58 | public static void reportUncaughtException(Throwable e) { 59 | // throw an exception "later" so that it ends up handled by the global 60 | // error handler. Same code as in GWT2's Impl.reportToBrowser() 61 | DomGlobal.setTimeout( 62 | ignore -> { 63 | throw_(e); 64 | }, 65 | 0); 66 | } 67 | 68 | /** 69 | * Returns the currently active uncaughtExceptionHandler. 70 | * 71 | * @return the currently active handler, or null if no handler is active. 72 | * @see #reportUncaughtException(Throwable) 73 | */ 74 | public static UncaughtExceptionHandler getUncaughtExceptionHandler() { 75 | return uncaughtExceptionHandler; 76 | } 77 | 78 | /** 79 | * Sets a custom uncaught exception handler. See {@link #getUncaughtExceptionHandler()} for 80 | * details. 81 | * 82 | * @param handler the handler that should be called when an exception is about to escape to the 83 | * browser, or null to clear the handler and allow exceptions to escape. 84 | */ 85 | public static void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) { 86 | uncaughtExceptionHandler = handler; 87 | if (handler == null) { 88 | return; 89 | } 90 | if (onErrorInitialized) { 91 | return; 92 | } 93 | onErrorInitialized = true; 94 | 95 | // transliterated from gwt2's Impl.registerWindowOnError 96 | Window.OnerrorFn errorHandler = 97 | (msg, url, line, column, error) -> { 98 | if (uncaughtExceptionHandler == null) { 99 | return null; 100 | } 101 | // IE8, IE9, IE10, safari 9, do not have an error passed. While 102 | // we don't necessarily support these browsers, when chasing an 103 | // error there is already enough frustration, so we'll still 104 | // synthesize a new one 105 | 106 | if (error == null) { 107 | String errorString = msg + " (" + url + ":" + line; 108 | // IE8 and IE9 do not have the column number 109 | if (Js.asAny(column) == null) { 110 | errorString += ":" + column; 111 | } 112 | errorString += ")"; 113 | uncaughtExceptionHandler.onUncaughtException(fromObject(errorString)); 114 | 115 | } else { 116 | uncaughtExceptionHandler.onUncaughtException(fromObject(error)); 117 | } 118 | 119 | return null; 120 | }; 121 | 122 | addOnErrorHandler(DomGlobal.window, errorHandler); 123 | if (DomGlobal.window != InnerWindow.window) { 124 | // if the local window is the same as the global one (SSO linker in gwt2, or default in j2cl) 125 | // we skip this 126 | addOnErrorHandler(InnerWindow.window, errorHandler); 127 | } 128 | } 129 | 130 | /** 131 | * Appends a new onerror handler so that both original and new are called, or just assigns the new 132 | * one if there was no existing one. 133 | */ 134 | private static void addOnErrorHandler(Window window, Window.OnerrorFn onerrorFn) { 135 | Window.OnerrorFn original = window.onerror; 136 | if (original == null) { 137 | window.onerror = onerrorFn; 138 | } else { 139 | window.onerror = 140 | (p0, p1, p2, p3, p4) -> { 141 | onerrorFn.onInvoke(p0, p1, p2, p3, p4); 142 | original.onInvoke(p0, p1, p2, p3, p4); 143 | return null; 144 | }; 145 | } 146 | } 147 | 148 | /** 149 | * Ugly hack to let j2cl and gwt both call the fake method Throwable.of, which only exists in our 150 | * emul code, not in the proper JRE. 151 | */ 152 | @JsMethod 153 | private static native Throwable fromObject(Object obj) /*-{ 154 | //GWT2 impl using JSNI, see GWT.native.js for the j2cl impl 155 | var throwable = @java.lang.Throwable::of(*)(obj); 156 | }-*/; 157 | 158 | @JsType(isNative = true, name = "window", namespace = "") 159 | private static class InnerWindow { 160 | static Window window; 161 | } 162 | 163 | @JsMethod(namespace = "", name = "throw") 164 | private static native void throw_(Object object); 165 | 166 | public static boolean isClient() { 167 | return org.gwtproject.core.shared.GWT.isClient(); 168 | } 169 | 170 | public static boolean isProdMode() { 171 | return org.gwtproject.core.shared.GWT.isProdMode(); 172 | } 173 | 174 | public static boolean isScript() { 175 | return org.gwtproject.core.shared.GWT.isScript(); 176 | } 177 | 178 | public static void log(String message) { 179 | org.gwtproject.core.shared.GWT.log(message); 180 | } 181 | 182 | public static void log(String message, Throwable e) { 183 | org.gwtproject.core.shared.GWT.log(message, e); 184 | } 185 | 186 | public static void debugger() { 187 | org.gwtproject.core.shared.GWT.debugger(); 188 | } 189 | 190 | public static void runAsync(Class name, Object ignore) { 191 | throw new UnsupportedOperationException( 192 | "Pick either GWT2 split point or Closure-Compiler chunks"); 193 | } 194 | 195 | public static void runAsync(Object ignore) { 196 | throw new UnsupportedOperationException( 197 | "Pick either GWT2 split point or Closure-Compiler chunks"); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/GWT.native.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | const javaLangThrowable = goog.forwardDeclare('java.lang.Throwable'); 17 | 18 | // fully qualified name apparently required since there are two non-native 19 | // types with the same name "GWT" 20 | org_gwtproject_core_client_GWT.fromObject = function(obj) { 21 | //j2cl impl to invoke java.lang.Throwable.of(Object) 22 | return javaLangThrowable.of(obj); 23 | }; -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JavaScriptObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.Function; 19 | import elemental2.core.JsArray; 20 | import jsinterop.annotations.JsConstructor; 21 | import jsinterop.annotations.JsOverlay; 22 | import jsinterop.annotations.JsPackage; 23 | import jsinterop.annotations.JsType; 24 | import jsinterop.base.Js; 25 | 26 | /** 27 | * Deprecated, only exists to ease migration of existing JSO types. 28 | * 29 | *

To update a JSO to support this type, add the appropriate @JsType annotation (may simply be a 30 | * copy from this class), and update each method. Each will either be * a native @JsProperty 31 | * (possibly with a name), * a native @JsMethod (possibly with a name), or * a final method written 32 | * in Java annotated with @JsOverlay, which may call any other methods. 33 | * 34 | *

Additionally, constructors may still exist as protected, no arg markers (as in the old 35 | * JavaScriptObject), or they may describe the actual underlying JS native type, but they must be 36 | * used in a manner consistent with JsInterop. 37 | */ 38 | @Deprecated 39 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 40 | public class JavaScriptObject { 41 | /** 42 | * Returns a new array. 43 | * 44 | * @return a new array 45 | */ 46 | @JsOverlay 47 | public static JavaScriptObject createArray() { 48 | return Js.cast(new JsArray<>()); 49 | } 50 | 51 | /** 52 | * Returns a new array with a given size. 53 | * 54 | *

Consider using this method in performance critical code instead of using {@link 55 | * #createArray()}, since this gives more hints to the underlying JavaScript VM for optimizations. 56 | * 57 | * @param size size of array 58 | * @return array as JavaScript object 59 | */ 60 | @JsOverlay 61 | public static JavaScriptObject createArray(int size) { 62 | return Js.cast(new JsArray<>((double) size)); 63 | } 64 | 65 | /** 66 | * Returns an empty function. 67 | * 68 | * @return function as JavaScript object 69 | */ 70 | @JsOverlay 71 | public static JavaScriptObject createFunction() { 72 | return Js.cast(new Function()); 73 | } 74 | 75 | /** 76 | * Returns a new object. 77 | * 78 | * @return object as JavaScript object 79 | */ 80 | @JsOverlay 81 | public static JavaScriptObject createObject() { 82 | return new JavaScriptObject(); 83 | } 84 | 85 | @JsConstructor 86 | protected JavaScriptObject() {} 87 | 88 | @JsOverlay 89 | public final T cast() { 90 | return Js.uncheckedCast(this); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import jsinterop.annotations.JsOverlay; 19 | import jsinterop.annotations.JsPackage; 20 | import jsinterop.annotations.JsType; 21 | import jsinterop.base.JsArrayLike; 22 | 23 | /** 24 | * A simple wrapper around a homogeneous native array of {@link 25 | * org.gwtproject.core.client.JavaScriptObject} values. 26 | * 27 | *

This class may not be directly instantiated, and can only be returned from a native method. 28 | * For example, 29 | * native JsArray<JavaScriptObject> getNativeArray() /*-{ 30 | * return [ 31 | * { x: 0, y: 1}, 32 | * { x: 2, y: 3}, 33 | * { x: 4, y: 5}, 34 | * ]; 35 | * }-* /; 36 | * 37 | * 38 | * @param the concrete type of object contained in this array 39 | */ 40 | @Deprecated 41 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 42 | public class JsArray extends JavaScriptObject { 43 | 44 | protected JsArray() {} 45 | 46 | /** 47 | * Gets the object at a given index. 48 | * 49 | * @param index the index to be retrieved 50 | * @return the object at the given index, or null if none exists 51 | */ 52 | @JsOverlay 53 | public final T get(int index) { 54 | return this.>cast().getAt(index); 55 | } 56 | 57 | /** 58 | * Convert each element of the array to a String and join them with a comma separator. The value 59 | * returned from this method may vary between browsers based on how JavaScript values are 60 | * converted into strings. 61 | * 62 | * @return resulting String 63 | */ 64 | @JsOverlay 65 | public final String join() { 66 | return this.>cast().join(); 67 | } 68 | 69 | /** 70 | * Convert each element of the array to a String and join them with a comma separator. The value 71 | * returned from this method may vary between browsers based on how JavaScript values are 72 | * converted into strings. 73 | * 74 | * @param separator separator to use 75 | * @return String containing all elements of the array. Each element separated using the separator 76 | */ 77 | @JsOverlay 78 | public final String join(String separator) { 79 | return this.>cast().join(separator); 80 | } 81 | 82 | /** 83 | * Gets the length of the array. 84 | * 85 | * @return the array length 86 | */ 87 | @JsOverlay 88 | public final int length() { 89 | return this.>cast().getLength(); 90 | } 91 | 92 | /** 93 | * Pushes the given value onto the end of the array. 94 | * 95 | * @param value value to push 96 | */ 97 | public final native void push(T value); 98 | 99 | /** 100 | * Sets the object value at a given index. 101 | * 102 | *

If the index is out of bounds, the value will still be set. The array's length will be 103 | * updated to encompass the bounds implied by the added object. 104 | * 105 | * @param index the index to be set 106 | * @param value the object to be stored 107 | */ 108 | @JsOverlay 109 | public final void set(int index, T value) { 110 | this.>cast().setAt(index, value); 111 | } 112 | 113 | /** 114 | * Reset the length of the array. 115 | * 116 | * @param newLength the new length of the array 117 | */ 118 | @JsOverlay 119 | public final void setLength(int newLength) { 120 | this.>cast().length = newLength; 121 | } 122 | 123 | /** 124 | * Shifts the first value off the array. 125 | * 126 | * @return the shifted value 127 | */ 128 | @JsOverlay 129 | public final T shift() { 130 | return this.>cast().shift(); 131 | } 132 | 133 | /** 134 | * Shifts a value onto the beginning of the array. 135 | * 136 | * @param value the value to the stored 137 | */ 138 | public final native void unshift(T value); 139 | } 140 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayBoolean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import jsinterop.annotations.JsOverlay; 19 | import jsinterop.annotations.JsPackage; 20 | import jsinterop.annotations.JsType; 21 | import jsinterop.base.JsArrayLike; 22 | 23 | /** 24 | * A simple wrapper around a homogeneous native array of boolean values. 25 | * 26 | *

This class may not be directly instantiated, and can only be returned from a native method. 27 | * For example, 28 | * native JsArrayBoolean getNativeArray() /*-{ 29 | * return [true, false, true]; 30 | * }-* /; 31 | * 32 | */ 33 | @Deprecated 34 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 35 | public class JsArrayBoolean extends JavaScriptObject { 36 | 37 | protected JsArrayBoolean() {} 38 | 39 | /** 40 | * Gets the value at a given index. 41 | * 42 | *

If an undefined or non-boolean value exists at the given index, a type-conversion error will 43 | * occur in Development Mode and unpredictable behavior may occur in Production Mode. 44 | * 45 | * @param index the index to be retrieved 46 | * @return the value at the given index 47 | */ 48 | @JsOverlay 49 | public final boolean get(int index) { 50 | return this.>cast().getAt(index); 51 | } 52 | 53 | /** 54 | * Convert each element of the array to a String and join them with a comma separator. The value 55 | * returned from this method may vary between browsers based on how JavaScript values are 56 | * converted into strings. 57 | * 58 | * @return all elements jointed into a String separated by comma 59 | */ 60 | @JsOverlay 61 | public final String join() { 62 | return this.>cast().join(); 63 | } 64 | 65 | /** 66 | * Convert each element of the array to a String and join them with a comma separator. The value 67 | * returned from this method may vary between browsers based on how JavaScript values are 68 | * converted into strings. 69 | * 70 | * @param separator separator to use 71 | * @return all elements jointed into a String separated by the given separator 72 | */ 73 | @JsOverlay 74 | public final String join(String separator) { 75 | return this.>cast().join(separator); 76 | } 77 | 78 | /** 79 | * Gets the length of the array. 80 | * 81 | * @return the array length 82 | */ 83 | @JsOverlay 84 | public final int length() { 85 | return this.>cast().getLength(); 86 | } 87 | 88 | /** 89 | * Pushes the given boolean onto the end of the array. 90 | * 91 | * @param value boolean value to push 92 | */ 93 | public final native void push(boolean value); 94 | 95 | /** 96 | * Sets the value value at a given index. 97 | * 98 | *

If the index is out of bounds, the value will still be set. The array's length will be 99 | * updated to encompass the bounds implied by the added value. 100 | * 101 | * @param index the index to be set 102 | * @param value the value to be stored 103 | */ 104 | @JsOverlay 105 | public final void set(int index, boolean value) { 106 | this.>cast().setAt(index, value); 107 | } 108 | 109 | /** 110 | * Reset the length of the array. 111 | * 112 | * @param newLength the new length of the array 113 | */ 114 | @JsOverlay 115 | public final void setLength(int newLength) { 116 | this.>cast().length = newLength; 117 | } 118 | 119 | /** 120 | * Shifts the first value off the array. 121 | * 122 | * @return the shifted value 123 | */ 124 | @JsOverlay 125 | public final boolean shift() { 126 | return this.>cast().shift(); 127 | } 128 | 129 | /** 130 | * Shifts a value onto the beginning of the array. 131 | * 132 | * @param value the value to the stored 133 | */ 134 | public final native void unshift(boolean value); 135 | } 136 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayInteger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.JsArray; 19 | import jsinterop.annotations.JsOverlay; 20 | import jsinterop.annotations.JsPackage; 21 | import jsinterop.annotations.JsType; 22 | import jsinterop.base.JsArrayLike; 23 | 24 | /** 25 | * A simple wrapper around a homogeneous native array of integer values. 26 | * 27 | *

This class may not be directly instantiated, and can only be returned from a native method. 28 | * For example, 29 | * native JsArrayInteger getNativeArray() /*-{ 30 | * return [1, 2, 3]; 31 | * }-* /; 32 | * 33 | */ 34 | @Deprecated 35 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 36 | public class JsArrayInteger extends JavaScriptObject { 37 | 38 | protected JsArrayInteger() {} 39 | 40 | /** 41 | * Gets the value at a given index. 42 | * 43 | *

If no value exists at the given index, a type-conversion error will occur in Development 44 | * Mode and unpredictable behavior may occur in Production Mode. If the numeric value returned is 45 | * non-integral, it will cause a warning in Development Mode, and may affect the results of 46 | * mathematical expressions. 47 | * 48 | * @param index the index to be retrieved 49 | * @return the value at the given index 50 | */ 51 | @JsOverlay 52 | public final int get(int index) { 53 | return (int) (double) this.>cast().getAt(index); 54 | } 55 | 56 | /** 57 | * Convert each element of the array to a String and join them with a comma separator. The value 58 | * returned from this method may vary between browsers based on how JavaScript values are 59 | * converted into strings. 60 | * 61 | * @return all elements jointed into a String separated by comma 62 | */ 63 | @JsOverlay 64 | public final String join() { 65 | return this.>cast().join(); 66 | } 67 | 68 | /** 69 | * Convert each element of the array to a String and join them with a comma separator. The value 70 | * returned from this method may vary between browsers based on how JavaScript values are 71 | * converted into strings. 72 | * 73 | * @param separator separator to use 74 | * @return all elements jointed into a String separated by the given separator 75 | */ 76 | @JsOverlay 77 | public final String join(String separator) { 78 | return this.>cast().join(separator); 79 | } 80 | 81 | /** 82 | * Gets the length of the array. 83 | * 84 | * @return the array length 85 | */ 86 | @JsOverlay 87 | public final int length() { 88 | return this.>cast().getLength(); 89 | } 90 | 91 | /** 92 | * Pushes the given integer onto the end of the array. 93 | * 94 | * @param value int value to push 95 | */ 96 | public final native void push(int value); 97 | 98 | /** 99 | * Sets the value value at a given index. 100 | * 101 | *

If the index is out of bounds, the value will still be set. The array's length will be 102 | * updated to encompass the bounds implied by the added value. 103 | * 104 | * @param index the index to be set 105 | * @param value the value to be stored 106 | */ 107 | @JsOverlay 108 | public final void set(int index, int value) { 109 | this.>cast().setAt(index, (double) value); 110 | } 111 | 112 | /** 113 | * Reset the length of the array. 114 | * 115 | * @param newLength the new length of the array 116 | */ 117 | @JsOverlay 118 | public final void setLength(int newLength) { 119 | this.>cast().length = newLength; 120 | } 121 | 122 | /** 123 | * Shifts the first value off the array. 124 | * 125 | * @return the shifted value 126 | */ 127 | @JsOverlay 128 | public final int shift() { 129 | return (int) (double) this.>cast().shift(); 130 | } 131 | 132 | /** 133 | * Shifts a value onto the beginning of the array. 134 | * 135 | * @param value the value to the stored 136 | */ 137 | public final native void unshift(int value); 138 | } 139 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayMixed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.JsArray; 19 | import jsinterop.annotations.JsOverlay; 20 | import jsinterop.annotations.JsPackage; 21 | import jsinterop.annotations.JsType; 22 | import jsinterop.base.Js; 23 | import jsinterop.base.JsArrayLike; 24 | 25 | /** 26 | * A simple wrapper around an heterogeneous native array of values. 27 | * 28 | *

This class may not be directly instantiated, and can only be returned from a native method. 29 | * For example, 30 | * native JsArrayMixed getNativeArray() /*-{ 31 | * return [ 32 | * { x: 0, y: 1}, 33 | * "apple", 34 | * 12345, 35 | * ]; 36 | * }-* /; 37 | * 38 | */ 39 | @Deprecated 40 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 41 | public class JsArrayMixed extends JavaScriptObject { 42 | 43 | protected JsArrayMixed() {} 44 | 45 | /** 46 | * Gets the boolean at a given index. 47 | * 48 | * @param index the index to be retrieved 49 | * @return the object at the given index coerced to boolean. 50 | */ 51 | @JsOverlay 52 | public final boolean getBoolean(int index) { 53 | return Js.isTruthy(this.>cast().getAtAsAny(index)); 54 | } 55 | 56 | /** 57 | * Gets the double at a given index. 58 | * 59 | * @param index the index to be retrieved 60 | * @return the object at the given index coerced to number. 61 | */ 62 | @JsOverlay 63 | public final double getNumber(int index) { 64 | return Js.coerceToDouble(this.>cast().getAtAsAny(index)); 65 | } 66 | 67 | /** 68 | * Gets the {@link org.gwtproject.core.client.JavaScriptObject} at a given index. 69 | * 70 | * @param type extending JavaScriptObject 71 | * @param index the index to be retrieved 72 | * @return the {@code JavaScriptObject} at the given index, or null if none exists 73 | */ 74 | @JsOverlay 75 | public final T getObject(int index) { 76 | return this.>cast().getAt(index) != null 77 | ? this.>cast().getAtAsAny(index).cast() 78 | : null; 79 | } 80 | 81 | /** 82 | * Gets the String at a given index. 83 | * 84 | * @param index the index to be retrieved 85 | * @return the object at the given index, or null if none exists 86 | */ 87 | @JsOverlay 88 | public final String getString(int index) { 89 | Object value = this.>cast().getAt(index); 90 | return value == null ? null : value.toString(); 91 | } 92 | 93 | /** 94 | * Convert each element of the array to a String and join them with a comma separator. The value 95 | * returned from this method may vary between browsers based on how JavaScript values are 96 | * converted into strings. 97 | * 98 | * @return all elements jointed into a String separated by comma 99 | */ 100 | @JsOverlay 101 | public final String join() { 102 | return this.>cast().join(); 103 | } 104 | 105 | /** 106 | * Convert each element of the array to a String and join them with a comma separator. The value 107 | * returned from this method may vary between browsers based on how JavaScript values are 108 | * converted into strings. 109 | * 110 | * @param separator separator to use 111 | * @return all elements jointed into a String separated by the given separator 112 | */ 113 | @JsOverlay 114 | public final String join(String separator) { 115 | return this.>cast().join(separator); 116 | } 117 | 118 | /** 119 | * Gets the length of the array. 120 | * 121 | * @return the array length 122 | */ 123 | @JsOverlay 124 | public final int length() { 125 | return this.>cast().getLength(); 126 | } 127 | 128 | /** 129 | * Pushes the given boolean onto the end of the array. 130 | * 131 | * @param value boolean value to push 132 | */ 133 | public final native void push(boolean value); 134 | 135 | /** 136 | * Pushes the given double onto the end of the array. 137 | * 138 | * @param value double value to push 139 | */ 140 | public final native void push(double value); 141 | 142 | /** 143 | * Pushes the given {@link org.gwtproject.core.client.JavaScriptObject} onto the end of the array. 144 | * 145 | * @param value JavaScriptObject value to push 146 | */ 147 | public final native void push(JavaScriptObject value); 148 | 149 | /** 150 | * Pushes the given String onto the end of the array. 151 | * 152 | * @param value String value to push 153 | */ 154 | public final native void push(String value); 155 | 156 | /** 157 | * Sets the boolean value at a given index. 158 | * 159 | *

If the index is out of bounds, the value will still be set. The array's length will be 160 | * updated to encompass the bounds implied by the added value. 161 | * 162 | * @param index the index to be set 163 | * @param value the boolean to be stored 164 | */ 165 | @JsOverlay 166 | public final void set(int index, boolean value) { 167 | this.>cast().setAt(index, value); 168 | } 169 | 170 | /** 171 | * Sets the double value at a given index. 172 | * 173 | *

If the index is out of bounds, the value will still be set. The array's length will be 174 | * updated to encompass the bounds implied by the added value. 175 | * 176 | * @param index the index to be set 177 | * @param value the double to be stored 178 | */ 179 | @JsOverlay 180 | public final void set(int index, double value) { 181 | this.>cast().setAt(index, value); 182 | } 183 | 184 | /** 185 | * Sets the object value at a given index. 186 | * 187 | *

If the index is out of bounds, the value will still be set. The array's length will be 188 | * updated to encompass the bounds implied by the added object. 189 | * 190 | * @param index the index to be set 191 | * @param value the {@link org.gwtproject.core.client.JavaScriptObject} to be stored 192 | */ 193 | @JsOverlay 194 | public final void set(int index, JavaScriptObject value) { 195 | this.>cast().setAt(index, value); 196 | } 197 | 198 | /** 199 | * Sets the String value at a given index. 200 | * 201 | *

If the index is out of bounds, the value will still be set. The array's length will be 202 | * updated to encompass the bounds implied by the added String. 203 | * 204 | * @param index the index to be set 205 | * @param value the String to be stored 206 | */ 207 | @JsOverlay 208 | public final void set(int index, String value) { 209 | this.>cast().setAt(index, value); 210 | } 211 | 212 | /** 213 | * Reset the length of the array. 214 | * 215 | * @param newLength the new length of the array 216 | */ 217 | @JsOverlay 218 | public final void setLength(int newLength) { 219 | this.>cast().length = newLength; 220 | } 221 | 222 | /** 223 | * Shifts the first value off the array. 224 | * 225 | * @return the shifted item coerced to a boolean 226 | */ 227 | @JsOverlay 228 | public final boolean shiftBoolean() { 229 | return Js.isTruthy(this.>cast().shift()); 230 | } 231 | 232 | /** 233 | * Shifts the first value off the array. 234 | * 235 | * @return the shifted item coerced to a number 236 | */ 237 | @JsOverlay 238 | public final double shiftNumber() { 239 | return Js.coerceToDouble(this.>cast().shift()); 240 | } 241 | 242 | /** 243 | * Shifts the first value off the array. 244 | * 245 | * @param type extending JavaScriptObject 246 | * @return the shifted {@link org.gwtproject.core.client.JavaScriptObject} 247 | */ 248 | @JsOverlay 249 | public final T shiftObject() { 250 | return Js.uncheckedCast(this.>cast().shift()); 251 | } 252 | 253 | /** 254 | * Shifts the first value off the array. 255 | * 256 | * @return the shifted String 257 | */ 258 | @JsOverlay 259 | public final String shiftString() { 260 | Object value = this.>cast().shift(); 261 | return value == null ? null : value.toString(); 262 | } 263 | 264 | /** 265 | * Shifts a boolean onto the beginning of the array. 266 | * 267 | * @param value the value to the stored 268 | */ 269 | public final native void unshift(boolean value); 270 | 271 | /** 272 | * Shifts a double onto the beginning of the array. 273 | * 274 | * @param value the value to store 275 | */ 276 | public final native void unshift(double value); 277 | 278 | /** 279 | * Shifts a {@link org.gwtproject.core.client.JavaScriptObject} onto the beginning of the array. 280 | * 281 | * @param value the value to store 282 | */ 283 | public final native void unshift(JavaScriptObject value); 284 | 285 | /** 286 | * Shifts a String onto the beginning of the array. 287 | * 288 | * @param value the value to store 289 | */ 290 | public final native void unshift(String value); 291 | } 292 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.JsArray; 19 | import jsinterop.annotations.JsOverlay; 20 | import jsinterop.annotations.JsPackage; 21 | import jsinterop.annotations.JsType; 22 | import jsinterop.base.Js; 23 | import jsinterop.base.JsArrayLike; 24 | 25 | /** 26 | * A simple wrapper around a homogeneous native array of numeric values. 27 | * 28 | *

All native JavaScript numeric values are implicitly double-precision, so only double values 29 | * may be set and retrieved. 30 | * 31 | *

This class may not be directly instantiated, and can only be returned from a native method. 32 | * For example, 33 | * native JsArrayNumber getNativeArray() /*-{ 34 | * return [1.1, 2.2, 3.3]; 35 | * }-* /; 36 | * 37 | */ 38 | @Deprecated 39 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 40 | public class JsArrayNumber extends JavaScriptObject { 41 | 42 | protected JsArrayNumber() {} 43 | 44 | /** 45 | * Gets the value at a given index. 46 | * 47 | *

If an undefined or non-numeric value exists at the given index, a type-conversion error will 48 | * occur in Development Mode and unpredictable behavior may occur in Production Mode. 49 | * 50 | * @param index the index to be retrieved 51 | * @return the value at the given index 52 | */ 53 | @JsOverlay 54 | public final double get(int index) { 55 | return this.>cast().getAt(index).doubleValue(); 56 | } 57 | 58 | /** 59 | * Convert each element of the array to a String and join them with a comma separator. The value 60 | * returned from this method may vary between browsers based on how JavaScript values are 61 | * converted into strings. 62 | * 63 | * @return all elements jointed into a String separated by comma 64 | */ 65 | @JsOverlay 66 | public final String join() { 67 | return this.>cast().join(); 68 | } 69 | 70 | /** 71 | * Convert each element of the array to a String and join them with a comma separator. The value 72 | * returned from this method may vary between browsers based on how JavaScript values are 73 | * converted into strings. 74 | * 75 | * @param separator separator to use 76 | * @return all elements jointed into a String separated by the given separator 77 | */ 78 | @JsOverlay 79 | public final String join(String separator) { 80 | return this.>cast().join(separator); 81 | } 82 | 83 | /** 84 | * Gets the length of the array. 85 | * 86 | * @return the array length 87 | */ 88 | @JsOverlay 89 | public final int length() { 90 | return this.>cast().getLength(); 91 | } 92 | 93 | /** 94 | * Pushes the given number onto the end of the array. 95 | * 96 | * @param value double value to push 97 | */ 98 | public final native void push(double value); 99 | 100 | /** 101 | * Sets the value value at a given index. 102 | * 103 | *

If the index is out of bounds, the value will still be set. The array's length will be 104 | * updated to encompass the bounds implied by the added value. 105 | * 106 | * @param index the index to be set 107 | * @param value the value to be stored 108 | */ 109 | @JsOverlay 110 | public final void set(int index, double value) { 111 | this.>cast().setAt(index, Js.uncheckedCast(value)); 112 | } 113 | 114 | /** 115 | * Reset the length of the array. 116 | * 117 | * @param newLength the new length of the array 118 | */ 119 | @JsOverlay 120 | public final void setLength(int newLength) { 121 | this.>cast().length = newLength; 122 | } 123 | 124 | /** 125 | * Shifts the first value off the array. 126 | * 127 | * @return the shifted value 128 | */ 129 | public final native double shift(); 130 | 131 | /** 132 | * Shifts a value onto the beginning of the array. 133 | * 134 | * @param value the value to the stored 135 | */ 136 | public final native void unshift(double value); 137 | } 138 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayString.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.core.JsArray; 19 | import jsinterop.annotations.JsOverlay; 20 | import jsinterop.annotations.JsPackage; 21 | import jsinterop.annotations.JsType; 22 | import jsinterop.base.Js; 23 | import jsinterop.base.JsArrayLike; 24 | 25 | /** 26 | * A simple wrapper around a homogeneous native array of string values. 27 | * 28 | *

This class may not be directly instantiated, and can only be returned from a native method. 29 | * For example, 30 | * native JsArrayString getNativeArray() /*-{ 31 | * return ['foo', 'bar', 'baz']; 32 | * }-* /; 33 | * 34 | */ 35 | @Deprecated 36 | @JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL) 37 | public class JsArrayString extends JavaScriptObject { 38 | 39 | protected JsArrayString() {} 40 | 41 | /** 42 | * Gets the value at a given index. 43 | * 44 | * @param index the index to be retrieved 45 | * @return the value at the given index, or null if none exists 46 | */ 47 | @JsOverlay 48 | public final String get(int index) { 49 | String value = this.>cast().getAt(index); 50 | return value == null ? null : value; 51 | } 52 | 53 | /** 54 | * Convert each element of the array to a String and join them with a comma separator. The value 55 | * returned from this method may vary between browsers based on how JavaScript values are 56 | * converted into strings. 57 | * 58 | * @return all elements jointed into a String separated by comma 59 | */ 60 | @JsOverlay 61 | public final String join() { 62 | return this.>cast().join(); 63 | } 64 | 65 | /** 66 | * Convert each element of the array to a String and join them with a comma separator. The value 67 | * returned from this method may vary between browsers based on how JavaScript values are 68 | * converted into strings. 69 | * 70 | * @param separator separator to use 71 | * @return all elements jointed into a String separated by the given separator 72 | */ 73 | @JsOverlay 74 | public final String join(String separator) { 75 | return this.>cast().join(separator); 76 | } 77 | 78 | /** 79 | * Gets the length of the array. 80 | * 81 | * @return the array length 82 | */ 83 | @JsOverlay 84 | public final int length() { 85 | return this.>cast().getLength(); 86 | } 87 | 88 | /** 89 | * Pushes the given value onto the end of the array. 90 | * 91 | * @param value String value to push 92 | */ 93 | public final native void push(String value); 94 | 95 | /** 96 | * Sets the value value at a given index. 97 | * 98 | *

If the index is out of bounds, the value will still be set. The array's length will be 99 | * updated to encompass the bounds implied by the added value. 100 | * 101 | * @param index the index to be set 102 | * @param value the value to be stored 103 | */ 104 | @JsOverlay 105 | public final void set(int index, String value) { 106 | this.>cast().setAt(index, Js.uncheckedCast(value)); 107 | } 108 | 109 | /** 110 | * Reset the length of the array. 111 | * 112 | * @param newLength the new length of the array 113 | */ 114 | @JsOverlay 115 | public final void setLength(int newLength) { 116 | this.>cast().length = newLength; 117 | } 118 | 119 | /** 120 | * Shifts the first value off the array. 121 | * 122 | * @return the shifted value 123 | */ 124 | public final native String shift(); 125 | 126 | /** 127 | * Shifts a value onto the beginning of the array. 128 | * 129 | * @param value the value to the stored 130 | */ 131 | public final native void unshift(String value); 132 | } 133 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsArrayUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import jsinterop.base.Js; 19 | 20 | /** 21 | * Utility class for manipulating JS arrays. These methods are not on other JavaScriptObject 22 | * subclasses, such as JsArray, because adding new methods might break existing subtypes. 23 | */ 24 | @Deprecated 25 | public class JsArrayUtils { 26 | 27 | /** 28 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 29 | * reference to the original array in prod mode, the source must not be modified while this copy 30 | * is in use or you will get different behavior between DevMode and prod mode. 31 | * 32 | * @param array source array 33 | * @return JS array, which may be a copy or an alias of the input array 34 | */ 35 | public static JsArrayInteger readOnlyJsArray(byte[] array) { 36 | return Js.uncheckedCast(array); 37 | } 38 | 39 | /** 40 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 41 | * reference to the original array in prod mode, the source must not be modified while this copy 42 | * is in use or you will get different behavior between DevMode and prod mode. 43 | * 44 | * @param array source array 45 | * @return JS array, which may be a copy or an alias of the input array 46 | */ 47 | public static JsArrayNumber readOnlyJsArray(double[] array) { 48 | return Js.uncheckedCast(array); 49 | } 50 | 51 | /** 52 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 53 | * reference to the original array in prod mode, the source must not be modified while this copy 54 | * is in use or you will get different behavior between DevMode and prod mode. 55 | * 56 | * @param array source array 57 | * @return JS array, which may be a copy or an alias of the input array 58 | */ 59 | public static JsArrayNumber readOnlyJsArray(float[] array) { 60 | return Js.uncheckedCast(array); 61 | } 62 | 63 | /** 64 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 65 | * reference to the original array in prod mode, the source must not be modified while this copy 66 | * is in use or you will get different behavior between DevMode and prod mode. 67 | * 68 | * @param array source array 69 | * @return JS array, which may be a copy or an alias of the input array 70 | */ 71 | public static JsArrayInteger readOnlyJsArray(int[] array) { 72 | return Js.uncheckedCast(array); 73 | } 74 | 75 | /** 76 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 77 | * reference to the original array in prod mode, the source must not be modified while this copy 78 | * is in use or you will get different behavior between DevMode and prod mode. 79 | * 80 | *

NOTE: long values are not supported in JS, so long emulation is slow and this method 81 | * assumes that all the values can be safely stored in a double. 82 | * 83 | * @param array source array - its values are assumed to be in the valid range for doubles -- if 84 | * the values exceed 2^53, low-order bits will be lost 85 | * @return JS array, which may be a copy or an alias of the input array 86 | */ 87 | public static JsArrayNumber readOnlyJsArray(long[] array) { 88 | return Js.uncheckedCast(array); 89 | } 90 | 91 | /** 92 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 93 | * reference to the original array in prod mode, the source must not be modified while this copy 94 | * is in use or you will get different behavior between DevMode and prod mode. 95 | * 96 | * @param array source array 97 | * @return JS array, which may be a copy or an alias of the input array 98 | */ 99 | public static JsArrayInteger readOnlyJsArray(short[] array) { 100 | return Js.uncheckedCast(array); 101 | } 102 | 103 | /** 104 | * Take a Java array, and produce a JS array that is only used for reading. As this is actually a 105 | * reference to the original array in prod mode, the source must not be modified while this copy 106 | * is in use or you will get different behavior between DevMode and prod mode. 107 | * 108 | * @param type extending JavaScriptObject 109 | * @param array source array 110 | * @return JS array, which may be a copy or an alias of the input array 111 | */ 112 | public static JsArray readOnlyJsArray(T[] array) { 113 | return Js.uncheckedCast(array); 114 | } 115 | 116 | private JsArrayUtils() {} 117 | } 118 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/JsonUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import static elemental2.core.Global.JSON; 19 | 20 | import elemental2.core.JSONType.StringifyReplacerUnionType; 21 | 22 | /** 23 | * Provides JSON-related utility methods. 24 | * 25 | *

Deprecated: just use JSON.parse and JSON.stringify. 26 | */ 27 | @Deprecated 28 | public class JsonUtils { 29 | 30 | /** 31 | * Converts a value to JSON. 32 | * 33 | * @param obj object to stringify 34 | * @return JSON value of the JavaScript object 35 | */ 36 | public static String stringify(JavaScriptObject obj) { 37 | return JSON.stringify(obj); 38 | } 39 | 40 | /** 41 | * Converts a value to JSON. 42 | * 43 | * @param obj object to stringify 44 | * @param space controls the spacing in the final string. Successive levels in the stringification 45 | * will each be indented by this string (or the first ten characters of it). 46 | * @return JSON value of the JavaScript object 47 | */ 48 | public static String stringify(JavaScriptObject obj, String space) { 49 | return JSON.stringify(obj, StringifyReplacerUnionType.of(null), space); 50 | } 51 | 52 | /** 53 | * Escapes characters within a JSON string than cannot be passed directly to eval(). Control 54 | * characters, quotes and backslashes are not affected. 55 | * 56 | * @param toEscape String to escape 57 | * @return same String 58 | */ 59 | public static String escapeJsonForEval(String toEscape) { 60 | // JsArray escapeTable = getEscapeTable(); 61 | // var s = 62 | // toEscape.replace(/[\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb]/g, function(x) { 63 | // return @JsonUtils::escapeChar(*)(x, escapeTable); 64 | // }); 65 | // return s; 66 | return toEscape; 67 | } 68 | 69 | /** 70 | * Escapes a value 71 | * 72 | * @param toEscape value to escape 73 | * @return a quoted, escaped JSON String. 74 | */ 75 | public static String escapeValue(String toEscape) { 76 | return JSON.stringify(toEscape); 77 | // JsArray escapeTable = getEscapeTable(); 78 | // var s = 79 | // toEscape.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g, function(x) { 80 | // return @JsonUtils::escapeChar(*)(x, escapeTable); 81 | // }); 82 | // return "\"" + s + "\""; 83 | } 84 | 85 | /** 86 | * Evaluates a JSON expression safely. The payload must evaluate to an Object or an Array (not a 87 | * primitive or a String). 88 | * 89 | * @param The type of JavaScriptObject that should be returned 90 | * @param json The source JSON text 91 | * @return The evaluated object 92 | * @throws IllegalArgumentException if the input is not valid JSON 93 | */ 94 | public static T safeEval(String json) { 95 | try { 96 | return (T) JSON.parse(json); 97 | } catch (Exception e) { 98 | throw new IllegalArgumentException(("Error parsing JSON: " + e) + "\n" + json); 99 | } 100 | } 101 | 102 | /** 103 | * Returns true if the given JSON string may be safely evaluated by {@code eval()} without 104 | * undesired side effects or security risks. Note that a true result from this method does not 105 | * guarantee that the input string is valid JSON. This method does not consider the contents of 106 | * quoted strings; it may still be necessary to perform escaping prior to evaluation for correct 107 | * results. 108 | * 109 | *

The technique used is taken from RFC 4627. 110 | * 111 | *

Note that this function may fail in sufficiently large text in some browsers (e.g. Chrome). 112 | * It is always better to use {@link #safeEval} instead which is safer, faster and also works with 113 | * large texts but less lenient than this one for invalid JSON. 114 | * 115 | * @param text text to test 116 | * @return true, always, all impls are safeEval now, never actually calling eval, they are all 117 | * safe 118 | */ 119 | public static boolean safeToEval(String text) { 120 | // Remove quoted strings and disallow anything except: 121 | // 122 | // 1) symbols and brackets ,:{}[] 123 | // 2) numbers: digits 0-9, ., -, +, e, and E 124 | // 3) literal values: 'null', 'true' and 'false' = [aeflnr-u] 125 | // 4) whitespace: ' ', '\n', '\r', and '\t' 126 | // return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, 127 | // ''))); 128 | return true; // all impls are safeEval now, never actually calling eval, they are all safe 129 | } 130 | 131 | /** 132 | * Evaluates a JSON expression using {@code eval()}. This method does not validate the JSON text 133 | * and should only be used on JSON from trusted sources. The payload must evaluate to an Object or 134 | * an Array (not a primitive or a String). 135 | * 136 | * @param The type of JavaScriptObject that should be returned 137 | * @param json The source JSON text 138 | * @return The evaluated object 139 | */ 140 | public static T unsafeEval(String json) { 141 | return safeEval(json); 142 | } 143 | 144 | // private static String escapeChar(String c, JavaScriptObject escapeTable) { 145 | // var lookedUp = @JsonUtils::escapeTable[c.charCodeAt(0)]; 146 | // return (lookedUp == null) ? c : lookedUp; 147 | // } 148 | // 149 | // private static JsArray escapeTable; // Lazily initialized. 150 | // 151 | // private static JsArray getEscapeTable() { 152 | // if (escapeTable == null) { 153 | // escapeTable = initEscapeTable(); 154 | // } 155 | // return escapeTable; 156 | // } 157 | // 158 | // private static JsArray initEscapeTable() { 159 | // var out = [ 160 | // "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", 161 | // "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000B", 162 | // "\\f", "\\r", "\\u000E", "\\u000F", "\\u0010", "\\u0011", 163 | // "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", 164 | // "\\u0018", "\\u0019", "\\u001A", "\\u001B", "\\u001C", "\\u001D", 165 | // "\\u001E", "\\u001F"]; 166 | // out[34] = '\\"'; 167 | // out[92] = '\\\\'; 168 | // out[0xad] = '\\u00ad'; // Soft hyphen 169 | // out[0x600] = '\\u0600'; // Arabic number sign 170 | // out[0x601] = '\\u0601'; // Arabic sign sanah 171 | // out[0x602] = '\\u0602'; // Arabic footnote marker 172 | // out[0x603] = '\\u0603'; // Arabic sign safha 173 | // out[0x6dd] = '\\u06dd'; // Arabic and of ayah 174 | // out[0x70f] = '\\u070f'; // Syriac abbreviation mark 175 | // out[0x17b4] = '\\u17b4'; // Khmer vowel inherent aq 176 | // out[0x17b5] = '\\u17b5'; // Khmer vowel inherent aa 177 | // out[0x200b] = '\\u200b'; // Zero width space 178 | // out[0x200c] = '\\u200c'; // Zero width non-joiner 179 | // out[0x200d] = '\\u200d'; // Zero width joiner 180 | // out[0x200e] = '\\u200e'; // Left-to-right mark 181 | // out[0x200f] = '\\u200f'; // Right-to-left mark 182 | // out[0x2028] = '\\u2028'; // Line separator 183 | // out[0x2029] = '\\u2029'; // Paragraph separator 184 | // out[0x202a] = '\\u202a'; // Left-to-right embedding 185 | // out[0x202b] = '\\u202b'; // Right-to-left embedding 186 | // out[0x202c] = '\\u202c'; // Pop directional formatting 187 | // out[0x202d] = '\\u202d'; // Left-to-right override 188 | // out[0x202e] = '\\u202e'; // Right-to-left override 189 | // out[0x2060] = '\\u2060'; // Word joiner 190 | // out[0x2061] = '\\u2061'; // Function application 191 | // out[0x2062] = '\\u2062'; // Invisible times 192 | // out[0x2063] = '\\u2063'; // Invisible separator 193 | // out[0x2064] = '\\u2064'; // Invisible plus 194 | // out[0x206a] = '\\u206a'; // Inhibit symmetric swapping 195 | // out[0x206b] = '\\u206b'; // Activate symmetric swapping 196 | // out[0x206c] = '\\u206c'; // Inherent Arabic form shaping 197 | // out[0x206d] = '\\u206d'; // Activate Arabic form shaping 198 | // out[0x206e] = '\\u206e'; // National digit shapes 199 | // out[0x206f] = '\\u206f'; // Nominal digit shapes 200 | // out[0xfeff] = '\\ufeff'; // Zero width no-break space 201 | // out[0xfff9] = '\\ufff9'; // Intralinear annotation anchor 202 | // out[0xfffa] = '\\ufffa'; // Intralinear annotation separator 203 | // out[0xfffb] = '\\ufffb'; // Intralinear annotation terminator 204 | // return out; 205 | // } 206 | 207 | private JsonUtils() {} 208 | } 209 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/Scheduler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import org.gwtproject.core.client.impl.SchedulerImpl; 19 | 20 | /** 21 | * This class provides low-level task scheduling primitives. Any exceptions thrown by the command 22 | * objects executed by the scheduler will be passed to the {@link 23 | * org.gwtproject.core.client.GWT.UncaughtExceptionHandler} if one is installed. 24 | * 25 | *

NOTE: If you are using a timer to schedule a UI animation, use See org/gwtproject/animation/client/AnimationScheduler.java 27 | * instead. The browser can optimize your animation for maximum performance. 28 | */ 29 | public abstract class Scheduler { 30 | 31 | /** General-purpose Command interface for tasks that repeat. */ 32 | public interface RepeatingCommand { 33 | /** @return true if the RepeatingCommand should be invoked again. */ 34 | boolean execute(); 35 | } 36 | 37 | /** General-purpose Command interface. */ 38 | public interface ScheduledCommand { 39 | /** Invokes the command. */ 40 | void execute(); 41 | } 42 | 43 | /** 44 | * Returns the default implementation of the Scheduler API. 45 | * 46 | * @return instance of Scheduler 47 | */ 48 | public static Scheduler get() { 49 | return SchedulerImpl.INSTANCE; 50 | } 51 | 52 | /** 53 | * A deferred command is executed after the browser event loop returns. 54 | * 55 | * @param cmd the command to execute 56 | */ 57 | public abstract void scheduleDeferred(ScheduledCommand cmd); 58 | 59 | /** 60 | * An "entry" command will be executed before GWT-generated code is invoked by the browser's event 61 | * loop. The {@link RepeatingCommand} will be called once per entry from the event loop until 62 | * false is returned. This type of command is appropriate for instrumentation or code 63 | * that needs to know when "something happens." 64 | * 65 | *

If an entry command schedules another entry command, the second command will be executed 66 | * before control flow continues to the GWT-generated code. 67 | * 68 | * @param cmd the command to execute 69 | */ 70 | @Deprecated 71 | public abstract void scheduleEntry(RepeatingCommand cmd); 72 | 73 | /** 74 | * An "entry" command will be executed before GWT-generated code is invoked by the browser's event 75 | * loop. This type of command is appropriate for code that needs to know when "something happens." 76 | * 77 | *

If an entry command schedules another entry command, the second command will be executed 78 | * before control flow continues to the GWT-generated code. 79 | * 80 | * @param cmd the command to execute 81 | */ 82 | @Deprecated 83 | public abstract void scheduleEntry(ScheduledCommand cmd); 84 | 85 | /** 86 | * A "finally" command will be executed before GWT-generated code returns control to the browser's 87 | * event loop. The {@link RepeatingCommand#execute()} method will be called once per exit to the 88 | * event loop until false is returned. This type of command is appropriate for 89 | * instrumentation or cleanup code. 90 | * 91 | *

If a finally command schedules another finally command, the second command will be executed 92 | * before control flow returns to the browser. 93 | * 94 | * @param cmd the command to execute 95 | */ 96 | public abstract void scheduleFinally(RepeatingCommand cmd); 97 | 98 | /** 99 | * A "finally" command will be executed before GWT-generated code returns control to the browser's 100 | * event loop. This type of command is used to aggregate small amounts of work before performing a 101 | * non-recurring, heavyweight operation. 102 | * 103 | *

If a finally command schedules another finally command, the second command will be executed 104 | * before control flow returns to the browser. 105 | * 106 | *

Consider the following: 107 | * 108 | *

109 |    * try {
110 |    *   nativeEventCallback(); // Calls scheduleFinally one or more times
111 |    * } finally {
112 |    *   executeFinallyCommands();
113 |    * }
114 |    * 
115 | * 116 | * see org.gwtproject.dom.client.StyleInjector 117 | * 118 | * @param cmd the command to execute 119 | */ 120 | public abstract void scheduleFinally(ScheduledCommand cmd); 121 | 122 | /** 123 | * Schedules a repeating command that is scheduled with a constant delay. That is, the next 124 | * invocation of the command will be scheduled for delayMs milliseconds after the 125 | * last invocation completes. 126 | * 127 | *

For example, assume that a command takes 30ms to run and a 100ms delay is provided. The 128 | * second invocation of the command will occur at 130ms after the first invocation starts. 129 | * 130 | * @param cmd the command to execute 131 | * @param delayMs the amount of time to wait after one invocation ends before the next invocation 132 | */ 133 | public abstract void scheduleFixedDelay(RepeatingCommand cmd, int delayMs); 134 | 135 | /** 136 | * Schedules a repeating command that is scheduled with a constant periodicity. That is, the 137 | * command will be invoked every delayMs milliseconds, regardless of how long the 138 | * previous invocation took to complete. 139 | * 140 | * @param cmd the command to execute 141 | * @param delayMs the period with which the command is executed 142 | */ 143 | public abstract void scheduleFixedPeriod(RepeatingCommand cmd, int delayMs); 144 | 145 | /** 146 | * Schedules a repeating command that performs incremental work. This type of command is 147 | * encouraged for long-running processes that perform computation or that manipulate the DOM. The 148 | * commands in this queue are invoked many times in rapid succession and are then deferred to 149 | * allow the browser to process its event queue. 150 | * 151 | * @param cmd the command to execute 152 | */ 153 | public abstract void scheduleIncremental(RepeatingCommand cmd); 154 | } 155 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/ScriptInjector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client; 17 | 18 | import elemental2.dom.Document; 19 | import elemental2.dom.DomGlobal; 20 | import elemental2.dom.HTMLScriptElement; 21 | import elemental2.dom.Window; 22 | import jsinterop.annotations.JsProperty; 23 | import jsinterop.annotations.JsType; 24 | import jsinterop.base.Any; 25 | import jsinterop.base.Js; 26 | import jsinterop.base.JsPropertyMap; 27 | 28 | public class ScriptInjector { 29 | 30 | /** Builder for directly injecting a script body into the DOM. */ 31 | public static class FromString { 32 | private boolean removeTag = true; 33 | private final String scriptBody; 34 | private Object window; 35 | 36 | /** @param scriptBody The script text to install into the document. */ 37 | public FromString(String scriptBody) { 38 | this.scriptBody = scriptBody; 39 | } 40 | 41 | /** 42 | * Injects a script into the DOM. The JavaScript is evaluated and will be available immediately 43 | * when this call returns. 44 | * 45 | *

By default, the script is installed in the same window that the GWT code is installed in. 46 | * 47 | * @return the script element created for the injection. Note that it may be removed from the 48 | * DOM. 49 | */ 50 | public JavaScriptObject inject() { 51 | Object wnd = (window == null) ? GwtAppHostWindow.nativeWindow : window; 52 | assert wnd != null; 53 | Document doc = 54 | Js.>uncheckedCast(wnd) 55 | .getAsAny("document") 56 | .uncheckedCast(); // window has no document property... TODO 57 | assert doc != null; 58 | 59 | // skipping the cast here since Chrome has a different HTMLScriptElement in the ifram 60 | HTMLScriptElement scriptElement = Js.uncheckedCast(doc.createElement("script")); 61 | assert scriptElement != null; 62 | scriptElement.text = scriptBody; 63 | doc.head.appendChild(scriptElement); 64 | if (removeTag) { 65 | scriptElement.parentNode.removeChild(scriptElement); 66 | } 67 | return Js.cast(scriptElement); 68 | } 69 | 70 | /** 71 | * @param removeTag If true, remove the tag immediately after injecting the source. This shrinks 72 | * the DOM, possibly at the expense of readability if you are debugging javaScript. 73 | *

Default value is {@code true}. 74 | * @return this 75 | */ 76 | public FromString setRemoveTag(boolean removeTag) { 77 | this.removeTag = removeTag; 78 | return this; 79 | } 80 | 81 | /** 82 | * @param window Specify which window to use to install the script. If not specified, the top 83 | * current window GWT is loaded in is used. 84 | * @return this 85 | */ 86 | public FromString setWindow(Object window) { 87 | this.window = window; 88 | return this; 89 | } 90 | } 91 | 92 | @JsType(isNative = true) 93 | private static final class GwtAppHostWindow { 94 | @JsProperty(namespace = "", name = "window") 95 | private static Window nativeWindow; 96 | } 97 | 98 | /** Build an injection call for adding a script by URL. */ 99 | public static class FromUrl { 100 | 101 | private Callback callback; 102 | private boolean removeTag = false; 103 | private final String scriptUrl; 104 | private Window window; 105 | 106 | private FromUrl(String scriptUrl) { 107 | this.scriptUrl = scriptUrl; 108 | } 109 | 110 | /** 111 | * Injects an external JavaScript reference into the document and optionally calls a callback 112 | * when it finishes loading. 113 | * 114 | * @return the script element created for the injection. 115 | */ 116 | public JavaScriptObject inject() { 117 | Window wnd = (window == null) ? GwtAppHostWindow.nativeWindow : window; 118 | assert wnd != null; 119 | Document doc = 120 | Js.>uncheckedCast(wnd) 121 | .getAsAny("document") 122 | .uncheckedCast(); // window has no document property... TODO 123 | assert doc != null; 124 | 125 | // skipping the cast here since Chrome has a different HTMLScriptElement in the ifram 126 | HTMLScriptElement scriptElement = Js.uncheckedCast(doc.createElement("script")); 127 | assert scriptElement != null; 128 | if (callback != null || removeTag) { 129 | attachListeners(scriptElement, callback, removeTag); 130 | } 131 | scriptElement.src = scriptUrl; 132 | doc.head.appendChild(scriptElement); 133 | return Js.cast(scriptElement); 134 | } 135 | 136 | /** 137 | * Specify a callback to be invoked when the script is loaded or loading encounters an error. 138 | * 139 | *

Warning: This class does not control whether or not a URL has already been 140 | * injected into the document. The client of this class has the responsibility of keeping score 141 | * of the injected JavaScript files. 142 | * 143 | *

Known bugs: This class uses the script tag's onerror() 144 | * callback to attempt to invoke onFailure() if the browser detects a load failure. This 145 | * is not reliable on all browsers (Doesn't work on IE or Safari 3 or less). 146 | * 147 | *

On Safari version 3 and prior, the onSuccess() callback may be invoked even when the load 148 | * of a page fails. 149 | * 150 | *

To support failure notification on IE and older browsers, you should check some side 151 | * effect of the script (such as a defined function) to see if loading the script worked and 152 | * include timeout logic. 153 | * 154 | * @param callback callback that gets invoked asynchronously. 155 | * @return this 156 | */ 157 | public FromUrl setCallback(Callback callback) { 158 | this.callback = callback; 159 | return this; 160 | } 161 | 162 | /** 163 | * @param removeTag If true, remove the tag after the script finishes loading. This shrinks the 164 | * DOM, possibly at the expense of readability if you are debugging javaScript. 165 | *

Default value is {@code false}, but this may change in a future release. 166 | * @return this 167 | */ 168 | public FromUrl setRemoveTag(boolean removeTag) { 169 | this.removeTag = removeTag; 170 | return this; 171 | } 172 | 173 | /** 174 | * This call allows you to specify which DOM window object to install the script tag in. To 175 | * install into the Top level window call 176 | * builder.setWindow(ScriptInjector.TOP_WINDOW); 177 | * 178 | * 179 | * @param window Specifies which window to install in. 180 | * @return this 181 | */ 182 | public FromUrl setWindow(Object window) { 183 | this.window = Js.uncheckedCast(window); 184 | return this; 185 | } 186 | } 187 | 188 | /** 189 | * Returns the top level window object. Use this to inject a script so that global variable 190 | * references are available under $wnd in JSNI access. 191 | * 192 | *

Note that if your GWT app is loaded from a different domain than the top window, you may not 193 | * be able to add a script element to the top window. 194 | */ 195 | public static final Object TOP_WINDOW = DomGlobal.window; 196 | 197 | /** 198 | * Build an injection call for directly setting the script text in the DOM. 199 | * 200 | * @param scriptBody the script text to be injected and immediately executed. 201 | * @return new FromString 202 | */ 203 | public static FromString fromString(String scriptBody) { 204 | return new FromString(scriptBody); 205 | } 206 | 207 | /** 208 | * Build an injection call for adding a script by URL. 209 | * 210 | * @param scriptUrl URL of the JavaScript to be injected. 211 | * @return new FromUrl 212 | */ 213 | public static FromUrl fromUrl(String scriptUrl) { 214 | return new FromUrl(scriptUrl); 215 | } 216 | 217 | /** 218 | * Attaches event handlers to a script DOM element that will run just once a callback when it gets 219 | * successfully loaded. 220 | * 221 | *

IE Notes: Internet Explorer calls {@code onreadystatechanged} several times while 222 | * varying the {@code readyState} property: in theory, {@code "complete"} means the content is 223 | * loaded, parsed and ready to be used, but in practice, {@code "complete"} happens when the JS 224 | * file was already cached, and {@code "loaded"} happens when it was transferred over the network. 225 | * Other browsers just call the {@code onload} event handler. To ensure the callback will be 226 | * called at most once, we clear out both event handlers when the callback runs for the first 227 | * time. More info at the phpied.com blog. 229 | * 230 | *

In IE, do not trust the "order" of {@code readyState} values. For instance, in IE 8 running 231 | * in Vista, if the JS file is cached, only {@code "complete"} will happen, but if the file has to 232 | * be downloaded, {@code "loaded"} can fire in parallel with {@code "loading"}. 233 | * 234 | * @param scriptElement element to which the event handlers will be attached 235 | * @param callback callback that runs when the script is loaded and parsed. 236 | */ 237 | private static void attachListeners( 238 | HTMLScriptElement scriptElement, Callback callback, boolean removeTag) { 239 | scriptElement.onload = 240 | e -> { 241 | if (callback != null) { 242 | callback.onSuccess(null); 243 | } 244 | if (removeTag) { 245 | scriptElement.parentNode.removeChild(scriptElement); 246 | } 247 | }; 248 | // or possibly more portable script_tag.addEventListener('error', function(){...}, true); 249 | scriptElement.onerror = 250 | e -> { 251 | if (callback != null) { 252 | callback.onFailure(new Exception("onerror() called.")); 253 | } 254 | if (removeTag) { 255 | scriptElement.parentNode.removeChild(scriptElement); 256 | } 257 | return null; 258 | }; 259 | } 260 | 261 | /** Utility class - do not instantiate */ 262 | private ScriptInjector() {} 263 | } 264 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/client/impl/SchedulerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.client.impl; 17 | 18 | import elemental2.core.JsArray; 19 | import elemental2.dom.DomGlobal; 20 | import elemental2.dom.DomGlobal.SetIntervalCallbackFn; 21 | import elemental2.dom.DomGlobal.SetTimeoutCallbackFn; 22 | import elemental2.promise.Promise; 23 | import jsinterop.annotations.JsOverlay; 24 | import jsinterop.annotations.JsPackage; 25 | import jsinterop.annotations.JsType; 26 | import jsinterop.base.Any; 27 | import jsinterop.base.Js; 28 | import org.gwtproject.core.client.Duration; 29 | import org.gwtproject.core.client.GWT; 30 | import org.gwtproject.core.client.Scheduler; 31 | 32 | /** This is used by Scheduler to collaborate with Impl in order to have FinallyCommands executed. */ 33 | public class SchedulerImpl extends Scheduler { 34 | /** 35 | * Metadata bag for command objects. It's a JSO so that a lightweight JsArray can be used instead 36 | * of a Collections type. 37 | */ 38 | @JsType(isNative = true, name = "Array", namespace = JsPackage.GLOBAL) 39 | static final class Task extends JsArray { 40 | @JsOverlay 41 | public static Task create(RepeatingCommand cmd) { 42 | return ((Task) new JsArray(Js.asAny(cmd), Js.asAny(true))); 43 | } 44 | 45 | @JsOverlay 46 | public static Task create(ScheduledCommand cmd) { 47 | return ((Task) new JsArray(Js.asAny(cmd), Js.asAny(false))); 48 | } 49 | 50 | @JsOverlay 51 | public boolean executeRepeating() { 52 | return getRepeating().execute(); 53 | } 54 | 55 | @JsOverlay 56 | public void executeScheduled() { 57 | getScheduled().execute(); 58 | } 59 | 60 | @JsOverlay 61 | public RepeatingCommand getRepeating() { 62 | return getAt(0).uncheckedCast(); 63 | } 64 | 65 | @JsOverlay 66 | public ScheduledCommand getScheduled() { 67 | return getAt(0).uncheckedCast(); 68 | } 69 | 70 | @JsOverlay 71 | public boolean isRepeating() { 72 | return getAt(1).asBoolean(); 73 | } 74 | } 75 | 76 | /** Calls {@link org.gwtproject.core.client.impl.SchedulerImpl#flushPostEventPumpCommands()}. */ 77 | private final class Flusher implements RepeatingCommand { 78 | public boolean execute() { 79 | flushRunning = true; 80 | flushPostEventPumpCommands(); 81 | /* 82 | * No finally here, we want this to be clear only on a normal exit. An 83 | * abnormal exit would indicate that an exception isn't being caught 84 | * correctly or that a slow script warning canceled the timer. 85 | */ 86 | flushRunning = false; 87 | return shouldBeRunning = isWorkQueued(); 88 | } 89 | } 90 | 91 | /** Keeps {@link Flusher} running. */ 92 | private final class Rescuer implements RepeatingCommand { 93 | public boolean execute() { 94 | if (flushRunning) { 95 | /* 96 | * Since JS is single-threaded, if we're here, then than means that 97 | * FLUSHER.execute() started, but did not finish. Reschedule FLUSHER. 98 | */ 99 | scheduleFixedDelay(flusher, FLUSHER_DELAY); 100 | } 101 | return shouldBeRunning; 102 | } 103 | } 104 | 105 | /** Use a GWT.create() here to make it simple to hijack the default implementation. */ 106 | public static final SchedulerImpl INSTANCE = new SchedulerImpl(); 107 | 108 | /** 109 | * The delay between flushing the task queues. Due to browser implementations the actual delay may 110 | * be longer. 111 | */ 112 | private static final int FLUSHER_DELAY = 1; 113 | 114 | /** The delay between checking up on SSW problems. */ 115 | private static final int RESCUE_DELAY = 50; 116 | 117 | /** 118 | * The amount of time that we're willing to spend executing IncrementalCommands. 16ms allows 119 | * control to be returned to the browser 60 times a second making it possible to keep the frame 120 | * rate at 60fps. 121 | */ 122 | private static final double TIME_SLICE = 16; 123 | 124 | /** Extract boilerplate code. */ 125 | private static JsArray createQueue() { 126 | return new JsArray<>(); 127 | } 128 | 129 | /** Called from scheduledFixedInterval to give $entry a static function. */ 130 | private static boolean execute(RepeatingCommand cmd) { 131 | return cmd.execute(); 132 | } 133 | 134 | /** Provides lazy-init pattern for the task queues. */ 135 | private static JsArray push(JsArray queue, Task task) { 136 | if (queue == null) { 137 | queue = createQueue(); 138 | } 139 | queue.push(task); 140 | return queue; 141 | } 142 | 143 | /** 144 | * Execute a list of Tasks that hold both ScheduledCommands and RepeatingCommands. Any 145 | * RepeatingCommands in the tasks queue that want to repeat will be pushed onto the 146 | * rescheduled queue. The contents of tasks may not be altered while 147 | * this method is executing. 148 | * 149 | * @return rescheduled or a newly-allocated array if rescheduled is 150 | * null. 151 | */ 152 | private static JsArray runScheduledTasks(JsArray tasks, JsArray rescheduled) { 153 | assert tasks != null : "tasks"; 154 | 155 | for (int i = 0, j = tasks.length; i < j; i++) { 156 | assert tasks.length == j : "Working array length changed " + tasks.length + " != " + j; 157 | Task t = tasks.getAt(i); 158 | 159 | try { 160 | // Move repeating commands to incremental commands queue 161 | if (t.isRepeating()) { 162 | if (t.executeRepeating()) { 163 | rescheduled = push(rescheduled, t); 164 | } 165 | } else { 166 | t.executeScheduled(); 167 | } 168 | } catch (Throwable e) { 169 | GWT.reportUncaughtException(e); 170 | } 171 | } 172 | return rescheduled; 173 | } 174 | 175 | private static void scheduleFixedDelayImpl(RepeatingCommand cmd, int delayMs) { 176 | DomGlobal.setTimeout( 177 | new SetTimeoutCallbackFn() { 178 | @Override 179 | public void onInvoke(Object... p0) { 180 | if (execute(cmd)) { 181 | DomGlobal.setTimeout(this, delayMs); 182 | } 183 | } 184 | }, 185 | delayMs); 186 | } 187 | 188 | private static void scheduleFixedPeriodImpl(RepeatingCommand cmd, int delayMs) { 189 | new SetIntervalCallbackFn() { 190 | double intervalId; 191 | 192 | // initializer exists to let us get the return value from scheduling 193 | { 194 | intervalId = DomGlobal.setInterval(this, delayMs); 195 | } 196 | 197 | @Override 198 | public void onInvoke(Object... p0) { 199 | if (!execute(cmd)) { 200 | // Either canceled or threw an exception 201 | DomGlobal.clearInterval(intervalId); 202 | } 203 | } 204 | }; 205 | } 206 | 207 | /** 208 | * A RepeatingCommand that calls flushPostEventPumpCommands(). It repeats if there are any 209 | * outstanding deferred or incremental commands. 210 | */ 211 | Flusher flusher; 212 | 213 | /** 214 | * This provides some backup for the main flusher task in case it gets shut down by a slow-script 215 | * warning. 216 | */ 217 | Rescuer rescue; 218 | 219 | /* 220 | * Work queues. Timers store their state on the function, so we don't need to 221 | * track them. They are not final so that we don't have to shorten them. 222 | * Processing the values in the queues is a one-shot, and then the array is 223 | * discarded. 224 | */ 225 | JsArray deferredCommands; 226 | // JsArray entryCommands; 227 | JsArray finallyCommands; 228 | JsArray incrementalCommands; 229 | 230 | /* 231 | * These two flags are used to control the state of the flusher and rescuer 232 | * commands. 233 | */ 234 | private boolean flushRunning = false; 235 | private boolean shouldBeRunning = false; 236 | 237 | /** Unused, since we have no $entry used on every JS call */ 238 | // public void flushEntryCommands() { 239 | // if (entryCommands != null) { 240 | // JsArray rescheduled = null; 241 | // // This do-while loop handles commands scheduling commands 242 | // do { 243 | // JsArray oldQueue = entryCommands; 244 | // entryCommands = null; 245 | // rescheduled = runScheduledTasks(oldQueue, rescheduled); 246 | // } while (entryCommands != null); 247 | // entryCommands = rescheduled; 248 | // } 249 | // } 250 | 251 | public void flushFinallyCommands() { 252 | if (finallyCommands != null) { 253 | JsArray rescheduled = null; 254 | // This do-while loop handles commands scheduling commands 255 | do { 256 | JsArray oldQueue = finallyCommands; 257 | finallyCommands = null; 258 | rescheduled = runScheduledTasks(oldQueue, rescheduled); 259 | } while (finallyCommands != null); 260 | finallyCommands = rescheduled; 261 | } 262 | } 263 | 264 | @Override 265 | public void scheduleDeferred(ScheduledCommand cmd) { 266 | deferredCommands = push(deferredCommands, Task.create(cmd)); 267 | maybeSchedulePostEventPumpCommands(); 268 | } 269 | 270 | @Override 271 | @Deprecated 272 | public void scheduleEntry(RepeatingCommand cmd) { 273 | // TODO possibly push to the old scheduler, if present 274 | } 275 | 276 | @Override 277 | @Deprecated 278 | public void scheduleEntry(ScheduledCommand cmd) { 279 | // TODO possibly push to the old scheduler, if present 280 | } 281 | 282 | @Override 283 | public void scheduleFinally(RepeatingCommand cmd) { 284 | if (finallyCommands == null) { 285 | Promise.resolve((Object) null) 286 | .then( 287 | ignore -> { 288 | flushFinallyCommands(); 289 | return null; 290 | }); 291 | } 292 | finallyCommands = push(finallyCommands, Task.create(cmd)); 293 | } 294 | 295 | @Override 296 | public void scheduleFinally(ScheduledCommand cmd) { 297 | if (finallyCommands == null) { 298 | Promise.resolve((Object) null) 299 | .then( 300 | ignore -> { 301 | flushFinallyCommands(); 302 | return null; 303 | }); 304 | } 305 | finallyCommands = push(finallyCommands, Task.create(cmd)); 306 | } 307 | 308 | @Override 309 | public void scheduleFixedDelay(RepeatingCommand cmd, int delayMs) { 310 | scheduleFixedDelayImpl(cmd, delayMs); 311 | } 312 | 313 | @Override 314 | public void scheduleFixedPeriod(RepeatingCommand cmd, int delayMs) { 315 | scheduleFixedPeriodImpl(cmd, delayMs); 316 | } 317 | 318 | @Override 319 | public void scheduleIncremental(RepeatingCommand cmd) { 320 | // Push repeating commands onto the same initial queue for relative order 321 | deferredCommands = push(deferredCommands, Task.create(cmd)); 322 | maybeSchedulePostEventPumpCommands(); 323 | } 324 | 325 | /** there for testing */ 326 | Duration createDuration() { 327 | return new Duration(); 328 | } 329 | 330 | /** Called by Flusher. */ 331 | void flushPostEventPumpCommands() { 332 | if (deferredCommands != null) { 333 | JsArray oldDeferred = deferredCommands; 334 | deferredCommands = null; 335 | 336 | /* We might not have any incremental commands queued. */ 337 | if (incrementalCommands == null) { 338 | incrementalCommands = createQueue(); 339 | } 340 | runScheduledTasks(oldDeferred, incrementalCommands); 341 | } 342 | 343 | if (incrementalCommands != null) { 344 | incrementalCommands = runRepeatingTasks(incrementalCommands); 345 | } 346 | } 347 | 348 | boolean isWorkQueued() { 349 | return deferredCommands != null || incrementalCommands != null; 350 | } 351 | 352 | private void maybeSchedulePostEventPumpCommands() { 353 | if (!shouldBeRunning) { 354 | shouldBeRunning = true; 355 | 356 | if (flusher == null) { 357 | flusher = new Flusher(); 358 | } 359 | scheduleFixedDelayImpl(flusher, FLUSHER_DELAY); 360 | 361 | if (rescue == null) { 362 | rescue = new Rescuer(); 363 | } 364 | scheduleFixedDelayImpl(rescue, RESCUE_DELAY); 365 | } 366 | } 367 | 368 | /** 369 | * Execute a list of Tasks that hold RepeatingCommands. 370 | * 371 | * @return A replacement array that is possibly a shorter copy of tasks 372 | */ 373 | private JsArray runRepeatingTasks(JsArray tasks) { 374 | assert tasks != null : "tasks"; 375 | 376 | int length = tasks.length; 377 | if (length == 0) { 378 | return null; 379 | } 380 | 381 | boolean canceledSomeTasks = false; 382 | 383 | Duration duration = createDuration(); 384 | while (duration.elapsedMillis() < TIME_SLICE) { 385 | boolean executedSomeTask = false; 386 | for (int i = 0; i < length; i++) { 387 | assert tasks.length == length 388 | : "Working array length changed " + tasks.length + " != " + length; 389 | Task t = tasks.getAt(i); 390 | if (t == null) { 391 | continue; 392 | } 393 | executedSomeTask = true; 394 | 395 | assert t.isRepeating() : "Found a non-repeating Task"; 396 | 397 | if (!t.executeRepeating()) { 398 | tasks.setAt(i, null); 399 | canceledSomeTasks = true; 400 | } 401 | } 402 | if (!executedSomeTask) { 403 | // no work left to do, break to avoid busy waiting until TIME_SLICE is reached 404 | break; 405 | } 406 | } 407 | 408 | if (canceledSomeTasks) { 409 | JsArray newTasks = createQueue(); 410 | // Remove tombstones 411 | for (int i = 0; i < length; i++) { 412 | if (tasks.getAt(i) != null) { 413 | newTasks.push(tasks.getAt(i)); 414 | } 415 | } 416 | assert newTasks.length < length; 417 | return newTasks.length == 0 ? null : newTasks; 418 | } else { 419 | return tasks; 420 | } 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/shared/GWT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.shared; 17 | 18 | import java.util.logging.Level; 19 | import java.util.logging.Logger; 20 | import jsinterop.base.Js; 21 | 22 | public final class GWT { 23 | private static final Logger log = Logger.getLogger("GWT.log()"); 24 | 25 | @Deprecated 26 | public static T create(Class classLiteral) { 27 | throw new UnsupportedOperationException( 28 | "GWT.create() no longer produces generated code. For legacy generators, use GWT2's GWT.create(), for annotation processors, read that library's documentation."); 29 | } 30 | 31 | public static boolean isClient() { 32 | return isScript(); 33 | } 34 | 35 | public static boolean isProdMode() { 36 | return isScript() 37 | && !("true".equals(System.getProperty("superdevmode", "false")) 38 | || "true".equals(System.getProperty("goog.DEBUG", "false"))); 39 | } 40 | 41 | public static boolean isScript() { 42 | return new JreImpl().isScript(); 43 | } 44 | 45 | public static void log(String message) { 46 | log(message, null); 47 | } 48 | 49 | public static void log(String message, Throwable e) { 50 | // forward all logs to juli 51 | log.log(Level.INFO, message, e); 52 | } 53 | 54 | public static void debugger() { 55 | // only insert debugger statement if in dev mode JS 56 | if (isScript() && !isProdMode()) { 57 | Js.debugger(); 58 | } 59 | } 60 | 61 | private static class GwtImpl { 62 | boolean isScript() { 63 | return true; 64 | } 65 | } 66 | 67 | private static class JreImpl extends GwtImpl { 68 | @GwtIncompatible 69 | @Override 70 | boolean isScript() { 71 | return false; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/shared/GwtIncompatible.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package org.gwtproject.core.shared; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * A simple of a GwtIncompatible annotation. 26 | * 27 | *

Any class, method or field with an annotation @GwtIncompatible (with any package prefix) is 28 | * ignored by the GWT compiler. 29 | * 30 | *

Since only the name of the annotation matters, Java libraries may use their own copy of this 31 | * annotation class to avoid adding a compile-time dependency on GWT. 32 | * 33 | *

For example: 34 | * 35 | *

36 | * class A { 37 | * 38 | * int field; 39 | * 40 | * @GwtIncompatible("incompatible class") 41 | * class Inner { 42 | * .... 43 | * } 44 | * 45 | * @GwtIncompatible("incompatible field") 46 | * int field2 = methodThatisNotSupportedbyGwt(); 47 | * 48 | * void method1() { 49 | * .... 50 | * } 51 | * 52 | * @GwtIncompatible("incompatbile method") 53 | * void method2() { 54 | * .... 55 | * } 56 | * } 57 | * 58 | * 59 | *

is seen by the Gwt compiler as 60 | * 61 | *

62 | * class A { 63 | * 64 | * int field; 65 | * 66 | * void method1() { } 67 | * 68 | * } 69 | * 70 | * 71 | *

Warning: this may have surprising effects when combined with method overloading or 72 | * inheritance. 73 | */ 74 | @Retention(RetentionPolicy.CLASS) 75 | @Target({ 76 | ElementType.TYPE, ElementType.METHOD, 77 | ElementType.CONSTRUCTOR, ElementType.FIELD 78 | }) 79 | @Documented 80 | public @interface GwtIncompatible { 81 | /** 82 | * An attribute that can be used to explain why the code is incompatible. A GwtIncompatible 83 | * annotation can have any number of attributes; attributes are for documentation purposes and are 84 | * ignored by the GWT compiler. 85 | * 86 | * @return reason why the test case is incompatible 87 | */ 88 | String value() default ""; 89 | } 90 | -------------------------------------------------------------------------------- /gwt-core/src/main/java/org/gwtproject/core/shared/gwtcore.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | goog.provide('gwtcore'); 17 | 18 | /** @define {string} */ 19 | var superdevmode = goog.define("superdevmode", goog.DEBUG ? "on" : "off"); -------------------------------------------------------------------------------- /gwt-core/src/main/module.gwt.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /gwt-core/src/test/java/org/gwtproject/core/shared/GWTTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 The GWT Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.gwtproject.core.shared; 17 | 18 | import static org.junit.Assert.assertFalse; 19 | 20 | import org.junit.Test; 21 | 22 | public class GWTTest { 23 | @Test 24 | public void testIsScript() { 25 | assertFalse(GWT.isScript()); 26 | assertFalse(org.gwtproject.core.shared.GWT.isScript()); 27 | } 28 | 29 | @Test 30 | public void testIsClient() { 31 | assertFalse(GWT.isClient()); 32 | assertFalse(org.gwtproject.core.shared.GWT.isClient()); 33 | } 34 | 35 | @Test 36 | public void testIsProdMode() { 37 | assertFalse(GWT.isProdMode()); 38 | assertFalse(org.gwtproject.core.shared.GWT.isProdMode()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.gwtproject.core 7 | gwt-core-parent 8 | 9 | dev 10 | 11 | pom 12 | 13 | GWT Core Parent 14 | Parent POM containing the gwt-core module and the test modules (gwt2- and j2cl-tests) 15 | https://github.com/gwtproject/gwt-core 16 | 17 | 18 | The GWT Project Authors 19 | https://github.com/gwtproject 20 | 21 | 22 | 23 | 24 | The Apache Software License, Version 2.0 25 | http://www.apache.org/licenses/LICENSE-2.0.txt 26 | 27 | 28 | 29 | 30 | 31 | The GWT Project Authors 32 | The GWT Project Authors 33 | https://github.com/gwtproject 34 | 35 | 36 | 37 | 38 | scm:git:git://github.com/gwtproject/gwt-core.git 39 | scm:git:ssh://github.com/gwtproject/gwt-core.git 40 | https://github.com/gwtproject/gwt-core/tree/master 41 | 42 | 43 | 2019 44 | 45 | 46 | gwt-core 47 | gwt-core-gwt2-tests 48 | gwt-core-j2cl-tests 49 | 50 | 51 | 52 | HEAD-SNAPSHOT 53 | 54 | UTF-8 55 | 56 | 1.8 57 | 1.8 58 | 59 | 3.8.1 60 | 3.0.0-M1 61 | 1.2.2 62 | 2.9 63 | 3.0.0-M1 64 | 3.0 65 | 3.0.0-M1 66 | 67 | 1.1.0 68 | 4.12 69 | 70 | 71 | 72 | 73 | 74 | com.coveo 75 | fmt-maven-plugin 76 | ${maven.fmt.plugin} 77 | 78 | 79 | 80 | check 81 | 82 | 83 | 84 | 85 | 86 | com.mycila 87 | license-maven-plugin 88 | ${maven.license.plugin} 89 | 90 |

LICENSE.header
91 | ${project.build.sourceEncoding} 92 | true 93 | 94 | SLASHSTAR_STYLE 95 | 96 | 97 | **/README.md 98 | **/LICENSE 99 | **/LICENSE.header 100 | **/AUTHORS 101 | **/src/test/resources/** 102 | **/src/main/resources/** 103 | **/pom.xml 104 | **/.flattened-pom.xml 105 | **/war 106 | **/gwt-unitcache 107 | 108 | 109 | ${project.inceptionYear} 110 | ${project.organization.name} 111 | 112 | 113 | 114 | 115 | 116 | check 117 | 118 | 119 | 120 | 121 | 122 | org.codehaus.mojo 123 | flatten-maven-plugin 124 | ${maven.flatten.plugin} 125 | 126 | oss 127 | 128 | 129 | 130 | flatten 131 | process-resources 132 | 133 | flatten 134 | 135 | 136 | 137 | flatten.clean 138 | clean 139 | 140 | clean 141 | 142 | 143 | 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-deploy-plugin 148 | ${maven.deploy.plugin} 149 | 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | org.apache.maven.plugins 158 | maven-compiler-plugin 159 | ${maven.compiler.plugin} 160 | 161 | ${maven.compiler.source} 162 | ${maven.compiler.target} 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | ${project.groupId} 174 | gwt-core 175 | ${project.version} 176 | test 177 | 178 | 179 | 180 | 181 | 182 | 183 | ossrh 184 | https://oss.sonatype.org/content/repositories/snapshots 185 | 186 | 187 | ossrh 188 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 189 | 190 | 191 | 192 | --------------------------------------------------------------------------------