├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── android
├── .gitignore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── kotlin
│ └── com
│ └── knoyo
│ └── flutter_jscore
│ └── FlutterJscorePlugin.kt
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ ├── jniLibs
│ │ │ ├── arm64-v8a
│ │ │ │ └── libc++_shared.so
│ │ │ ├── armeabi-v7a
│ │ │ │ └── libc++_shared.so
│ │ │ ├── x86
│ │ │ │ └── libc++_shared.so
│ │ │ └── x86_64
│ │ │ │ └── libc++_shared.so
│ │ ├── libs
│ │ │ └── android-jsc-intl-r250230.aar
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── knoyo
│ │ │ │ │ └── flutter_jscore_example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── art
│ ├── apk_QRCode.png
│ ├── flutter_jscore.apk
│ └── flutter_jscore.gif
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── example.dart
│ ├── main.dart
│ ├── utils
│ │ └── h2dart.dart
│ └── views
│ │ ├── bindings_page.dart
│ │ ├── h2dart_page.dart
│ │ └── jscore_page.dart
├── linux
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ ├── main.cc
│ ├── my_application.cc
│ └── my_application.h
├── macos
│ ├── .gitignore
│ ├── Flutter
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_512.png
│ │ │ └── app_icon_64.png
│ │ ├── Base.lproj
│ │ └── MainMenu.xib
│ │ ├── Configs
│ │ ├── AppInfo.xcconfig
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── test
│ └── widget_test.dart
├── web
│ ├── favicon.png
│ ├── icons
│ │ ├── Icon-192.png
│ │ └── Icon-512.png
│ ├── index.html
│ └── manifest.json
└── windows
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── JavaScriptCore
│ ├── ASL.dll
│ ├── CoreFoundation.dll
│ ├── JavaScriptCore.dll
│ ├── WTF.dll
│ ├── icudt62.dll
│ ├── libdispatch.dll
│ ├── libicuin.dll
│ ├── libicuuc.dll
│ └── objc.dll
│ ├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
│ └── runner
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── resources
│ └── app_icon.ico
│ ├── run_loop.cpp
│ ├── run_loop.h
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── FlutterJscorePlugin.h
│ ├── FlutterJscorePlugin.m
│ └── SwiftFlutterJscorePlugin.swift
└── flutter_jscore.podspec
├── lib
├── binding
│ ├── js_base.dart
│ ├── js_context_ref.dart
│ ├── js_object_ref.dart
│ ├── js_string_ref.dart
│ ├── js_typed_array.dart
│ ├── js_value_ref.dart
│ └── jsc_ffi.dart
├── flutter_jscore.dart
├── jscore
│ ├── js_class.dart
│ ├── js_context.dart
│ ├── js_context_group.dart
│ ├── js_object.dart
│ ├── js_property_name_accumulator.dart
│ ├── js_property_name_array.dart
│ ├── js_string.dart
│ └── js_value.dart
└── jscore_bindings.dart
├── linux
├── CMakeLists.txt
├── flutter_jscore_plugin.cc
└── include
│ └── flutter_jscore
│ └── flutter_jscore_plugin.h
├── macos
├── Classes
│ └── FlutterJscorePlugin.swift
└── flutter_jscore.podspec
├── pubspec.lock
├── pubspec.yaml
├── test
└── flutter_jscore_test.dart
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter_jscore_plugin.cpp
└── include
└── flutter_jscore
└── flutter_jscore_plugin.h
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | .idea
8 | .vagrant/
9 | .sconsign.dblite
10 | .svn/
11 |
12 | *.swp
13 | profile
14 |
15 | DerivedData/
16 |
17 | .generated/
18 |
19 | *.pbxuser
20 | *.mode1v3
21 | *.mode2v3
22 | *.perspectivev3
23 |
24 | !default.pbxuser
25 | !default.mode1v3
26 | !default.mode2v3
27 | !default.perspectivev3
28 |
29 | xcuserdata
30 |
31 | *.moved-aside
32 |
33 | *.pyc
34 | *sync/
35 | Icon?
36 | .tags*
37 |
38 | build/
39 | .android/
40 | .ios/
41 | .flutter-plugins
42 | *.iml
43 | .metadata
44 | pubspec.lock
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 67826bdce54505760fe83b7ead70bdb5af6fe9f2
8 | channel: dev
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.0.0
2 | > Add: null safety.
3 | > Add: Windows support.
4 | > Add: Linux support.
5 | > Update: Android dynamic library.
6 |
7 | ## 0.1.1
8 | > Fix: Some callback functions have no return value type.
9 | > Add: JavaScript context group create constructor.
10 | > Update: Transfer JavaScript context group retain and release functions to JSContextGroup.
11 |
12 | ## 0.1.0
13 | > Add: flutter_jscore example.
14 | > Update: documentation.
15 |
16 | ## 0.0.1
17 | > Add: JavaScript for Flutter.
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 xuelongqy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter_jscore
2 |
3 | [](/LICENSE)
4 | [](https://stackoverflow.com/questions/tagged/flutter?sort=votes)
5 | [](https://pub.flutter-io.cn/packages/flutter_jscore)
6 |
7 | JavaScriptCore for Flutter. The plugin provides the ability to evaluate JavaScript programs from within dart.
8 |
9 | ### Demo
10 | |Screen recording|Apk|
11 | |:---:|:---:|
12 | |||
13 | |[Code](https://github.com/xuelongqy/flutter_jscore/blob/master/example/lib/views/jscore_page.dart)|[Download](https://raw.githubusercontent.com/xuelongqy/flutter_jscore/master/example/art/flutter_jscore.apk)|
14 |
15 | ## Getting Started
16 |
17 | ### Add plugin
18 | ```yaml
19 | // pub
20 | dependencies:
21 | flutter_jscore: ^last_version
22 |
23 | // import
24 | dependencies:
25 | flutter_jscore:
26 | path: Your local path
27 |
28 | // git
29 | dependencies:
30 | flutter_jscore:
31 | git:
32 | url: git://github.com/xuelongqy/flutter_jscore.git
33 | ```
34 |
35 | ### Add dynamic library
36 |
37 | Due to the size limitation of pub on package upload, you need to add JavaScriptCore dynamic library to the project by yourself.
38 | You can refer to the [example](https://github.com/xuelongqy/flutter_jscore/tree/master/example). of course you can refer to [webkit](https://webkit.org/getting-the-code/) to compile it.
39 | Set JscFfi.lib to use the JavaScriptCore dynamic library.
40 | ```dart
41 | JscFfi.lib = Platform.isIOS || Platform.isMacOS
42 | ? DynamicLibrary.open('JavaScriptCore.framework/JavaScriptCore')
43 | : Platform.isWindows
44 | ? DynamicLibrary.open('JavaScriptCore.dll')
45 | : Platform.isLinux
46 | ? DynamicLibrary.open('libjavascriptcoregtk-4.0.so.18')
47 | : DynamicLibrary.open('libjsc.so');
48 | ```
49 |
50 | #### Android
51 |
52 | You can get the aar file containing libjsc.so in [jsc-android](https://www.npmjs.com/package/jsc-android), and add to your project.
53 | Take the [libs](https://github.com/xuelongqy/flutter_jscore/tree/master/example/android/app/libs) folder as an example, add it to the build.gradle of the module.
54 | ```groovy
55 | android {
56 | repositories {
57 | flatDir {
58 | dirs 'libs'
59 | }
60 | }
61 | }
62 | dependencies {
63 | implementation(name:'**', ext:'aar')
64 | }
65 | ```
66 | You also need to add libc++_shared.so, because this is a dependency of libjsc.so.
67 | Take the [jniLibs](https://github.com/xuelongqy/flutter_jscore/tree/master/example/android/app/jniLibs) folder as an example, add it to the build.gradle of the module.
68 | ```groovy
69 | android {
70 | sourceSets {
71 | main {
72 | jniLibs.srcDirs = ['jniLibs']
73 | }
74 | }
75 | }
76 | ```
77 | If your project uses C++, then you can add the code in the module’s build.gradle.
78 | ```groovy
79 | android {
80 | defaultConfig {
81 | externalNativeBuild {
82 | make {
83 | arguments "-DANDROID_STL=c++_shared"
84 | }
85 | }
86 | }
87 | }
88 | ```
89 |
90 | #### iOS and macOS
91 |
92 | You don’t need to do anything, because JavaScriptCore comes with iOS and macOS.
93 |
94 | #### Windows
95 |
96 | You can use the dynamic library in the [example](https://github.com/xuelongqy/flutter_jscore/tree/master/example/windows/JavaScriptCore), or compile it yourself. And configure in CMakeLists.txt.
97 | ```text
98 | # Add JavaScriptCore libs
99 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/JavaScriptCore/"
100 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
101 | COMPONENT Runtime)
102 | ```
103 |
104 | #### Linux
105 |
106 | You can use libjavascriptcoregtk as a dependency, or compile [webkitgtk](https://webkitgtk.org/) yourself.
107 | The names of dynamic libraries in different Linux distributions may be different. So you need to set JscFfi.lib.
108 |
109 | ubuntn or Debian
110 | ```shell
111 | apt-get install libjavascriptcoregtk-4.0-18
112 | ```
113 | ```dart
114 | JscFfi.lib = DynamicLibrary.open('libjavascriptcoregtk-4.0.so.18');
115 | ```
116 |
117 | Archlinux
118 | ```shell
119 | pacman -S webkit2gtk
120 | ```
121 | ```dart
122 | JscFfi.lib = DynamicLibrary.open('libjavascriptcoregtk-4.0.so');
123 | ```
124 |
125 | ### Usage
126 | ```dart
127 | import 'package:flutter_jscore/flutter_jscore.dart';
128 |
129 | void runJS() {
130 | JSContext jsContext = JSContext.createInGroup();
131 | // Replace '1 + 1' with your JavaScript code
132 | JSValue jsValue = jsContext.evaluate('1 + 1');
133 | print(jsValue.string);
134 | jsContext.release();
135 | }
136 | ```
137 |
138 | ## JavaScriptCore
139 |
140 | Evaluate JavaScript programs from within an app, and support JavaScript scripting of your app.
141 |
142 | [Documentation](https://developer.apple.com/documentation/javascriptcore)
143 |
144 | ## dart:ffi
145 |
146 | Foreign Function Interface for interoperability with the C programming language. flutter_jscore uses dart:ffi so you don't have to worry about performance loss across programming languages.
147 |
148 | [dart:ffi](https://api.dart.dev/stable/dart-ffi/dart-ffi-library.html)
149 |
150 | ## Supported platforms
151 |
152 | - iOS (7.0+)
153 | - macOS (10.5+)
154 | - Android (arm32, arm64, x86, x86_64)
155 | - Windows (x86_64)
156 | - Linux (x86_64)
157 |
158 | ## Linux dependencies
159 |
160 | If you use it on Linux, you must make sure to have the following dependencies.
161 |
162 | - libglib-2.0.so.0
163 | - libicui18n.so.66
164 | - libicuuc.so.66
165 | - libdl.so.2
166 | - libgio-2.0.so.0
167 | - libgobject-2.0.so.0
168 | - libpthread.so.0
169 | - libstdc++.so.6
170 | - libm.so.6
171 | - libgcc_s.so.1
172 | - libc.so.6
173 | - ld-linux-x86-64.so.2
174 |
175 | ## APIs
176 |
177 | I don't think there is much to describe, flutter_jscore just makes a simple package. You can refer to the documentation of JavaScriptCore and the documentation on pub.
178 |
179 | [JavaScriptCore](https://developer.apple.com/documentation/javascriptcore)
180 |
181 | [flutter_jscore](https://pub.dev/documentation/flutter_jscore/latest/)
182 |
183 | ## Donation
184 | If you like my project, please in the upper right corner of the project "Star". Your support is my biggest encouragement! ^_^
185 | You can also scan the qr code below or [](https://www.paypal.com/paypalme/xuelongqy), donation to Author.
186 |
187 |   
188 |
189 | If in donation message note name, will be record to the list if you are making open source authors, donation can leave when making project address or personal home page, a link will be added to the list have the effect of promoting each other
190 |
191 | [Donation list](https://github.com/xuelongqy/donation/blob/master/DONATIONLIST.md)
192 |
193 | ### QQ Group - 554981921
194 | #### Into the group of instructions
195 | The group is not only solve the problem of EasyreFresh, any Flutter related issues can be discussed. Just as its name, craigslist, as long as there is time, group of Lord will help you solve problems together.
196 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.knoyo.flutter_jscore'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.3.50'
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.5.0'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | rootProject.allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | }
22 | }
23 |
24 | apply plugin: 'com.android.library'
25 | apply plugin: 'kotlin-android'
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | sourceSets {
31 | main.java.srcDirs += 'src/main/kotlin'
32 | }
33 | defaultConfig {
34 | minSdkVersion 16
35 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
36 | }
37 | lintOptions {
38 | disable 'InvalidPackage'
39 | }
40 | }
41 |
42 | dependencies {
43 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
44 | }
45 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'flutter_jscore'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/knoyo/flutter_jscore/FlutterJscorePlugin.kt:
--------------------------------------------------------------------------------
1 | package com.knoyo.flutter_jscore
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.engine.plugins.FlutterPlugin
5 | import io.flutter.plugin.common.MethodCall
6 | import io.flutter.plugin.common.MethodChannel
7 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler
8 | import io.flutter.plugin.common.MethodChannel.Result
9 | import io.flutter.plugin.common.PluginRegistry.Registrar
10 |
11 | /** FlutterJscorePlugin */
12 | public class FlutterJscorePlugin: FlutterPlugin, MethodCallHandler {
13 | /// The MethodChannel that will the communication between Flutter and native Android
14 | ///
15 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it
16 | /// when the Flutter Engine is detached from the Activity
17 | private lateinit var channel : MethodChannel
18 |
19 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
20 | channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_jscore")
21 | channel.setMethodCallHandler(this);
22 | }
23 |
24 | // This static function is optional and equivalent to onAttachedToEngine. It supports the old
25 | // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
26 | // plugin registration via this function while apps migrate to use the new Android APIs
27 | // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
28 | //
29 | // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
30 | // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
31 | // depending on the user's project. onAttachedToEngine or registerWith must both be defined
32 | // in the same class.
33 | companion object {
34 | @JvmStatic
35 | fun registerWith(registrar: Registrar) {
36 | val channel = MethodChannel(registrar.messenger(), "flutter_jscore")
37 | channel.setMethodCallHandler(FlutterJscorePlugin())
38 | }
39 | }
40 |
41 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
42 | if (call.method == "getPlatformVersion") {
43 | result.success("Android ${android.os.Build.VERSION.RELEASE}")
44 | } else {
45 | result.notImplemented()
46 | }
47 | }
48 |
49 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
50 | channel.setMethodCallHandler(null)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea
18 |
19 | # Visual Studio Code related
20 | .vscode/
21 |
22 | # Flutter/Dart/Pub related
23 | **/doc/api/
24 | .dart_tool/
25 | .flutter-plugins
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 |
40 | # iOS/XCode related
41 | **/ios/**/*.mode1v3
42 | **/ios/**/*.mode2v3
43 | **/ios/**/*.moved-aside
44 | **/ios/**/*.pbxuser
45 | **/ios/**/*.perspectivev3
46 | **/ios/**/*sync/
47 | **/ios/**/.sconsign.dblite
48 | **/ios/**/.tags*
49 | **/ios/**/.vagrant/
50 | **/ios/**/DerivedData/
51 | **/ios/**/Icon?
52 | **/ios/**/Pods/
53 | **/ios/**/.symlinks/
54 | **/ios/**/profile
55 | **/ios/**/xcuserdata
56 | **/ios/.generated/
57 | **/ios/Flutter/App.framework
58 | **/ios/Flutter/Flutter.framework
59 | **/ios/Flutter/Generated.xcconfig
60 | **/ios/Flutter/app.flx
61 | **/ios/Flutter/app.zip
62 | **/ios/Flutter/flutter_assets/
63 | **/ios/ServiceDefinitions.json
64 | **/ios/Runner/GeneratedPluginRegistrant.*
65 |
66 | # Exceptions to above rules.
67 | !**/ios/**/default.mode1v3
68 | !**/ios/**/default.mode2v3
69 | !**/ios/**/default.pbxuser
70 | !**/ios/**/default.perspectivev3
71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
72 | .metadata
73 | pubspec.lock
74 | ios/.generated/
75 | ios/Flutter/Generated.xcconfig
76 | ios/Runner/GeneratedPluginRegistrant.*
77 | /lib/generated_plugin_registrant.dart
78 | .flutter-plugins-dependencies
79 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 67826bdce54505760fe83b7ead70bdb5af6fe9f2
8 | channel: dev
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # flutter_jscore_example
2 |
3 | Demonstrates how to use the flutter_jscore plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 28
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.knoyo.flutter_jscore_example"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 |
57 | repositories {
58 | flatDir {
59 | dirs 'libs'
60 | }
61 | }
62 |
63 | sourceSets {
64 | main {
65 | jniLibs.srcDirs = ['jniLibs']
66 | }
67 | }
68 | }
69 |
70 | flutter {
71 | source '../..'
72 | }
73 |
74 | dependencies {
75 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
76 | testImplementation 'junit:junit:4.12'
77 | androidTestImplementation 'androidx.test:runner:1.1.1'
78 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
79 | implementation(name:'android-jsc-intl-r250230', ext:'aar')
80 | }
81 |
--------------------------------------------------------------------------------
/example/android/app/jniLibs/arm64-v8a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/jniLibs/arm64-v8a/libc++_shared.so
--------------------------------------------------------------------------------
/example/android/app/jniLibs/armeabi-v7a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/jniLibs/armeabi-v7a/libc++_shared.so
--------------------------------------------------------------------------------
/example/android/app/jniLibs/x86/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/jniLibs/x86/libc++_shared.so
--------------------------------------------------------------------------------
/example/android/app/jniLibs/x86_64/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/jniLibs/x86_64/libc++_shared.so
--------------------------------------------------------------------------------
/example/android/app/libs/android-jsc-intl-r250230.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/libs/android-jsc-intl-r250230.aar
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
23 |
27 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/knoyo/flutter_jscore_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.knoyo.flutter_jscore_example
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.android.FlutterActivity
5 | import io.flutter.embedding.engine.FlutterEngine
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
10 | GeneratedPluginRegistrant.registerWith(flutterEngine);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/art/apk_QRCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/art/apk_QRCode.png
--------------------------------------------------------------------------------
/example/art/flutter_jscore.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/art/flutter_jscore.apk
--------------------------------------------------------------------------------
/example/art/flutter_jscore.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/art/flutter_jscore.gif
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_jscore_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/example/lib/example.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'package:flutter_jscore/flutter_jscore.dart';
4 |
5 | void main() => runApp(MyApp());
6 |
7 | class MyApp extends StatelessWidget {
8 | @override
9 | Widget build(BuildContext context) {
10 | return MaterialApp(
11 | title: 'flutter_jscore',
12 | home: _JSCorePage(),
13 | );
14 | }
15 | }
16 |
17 | class _JSCorePage extends StatefulWidget {
18 | @override
19 | _JSCorePageState createState() => _JSCorePageState();
20 | }
21 |
22 | class _JSCorePageState extends State<_JSCorePage> {
23 | late TextEditingController _jsInputController;
24 | late JSContext _jsContext;
25 |
26 | @override
27 | void initState() {
28 | super.initState();
29 | _jsContext = JSContext.createInGroup();
30 | _jsInputController = TextEditingController(text: '1 + 1');
31 | }
32 |
33 | @override
34 | void dispose() {
35 | _jsContext.release();
36 | _jsInputController.dispose();
37 | super.dispose();
38 | }
39 |
40 | String _runJs(String script) {
41 | var jsValue = _jsContext.evaluate(script);
42 | return jsValue.string ?? 'No result';
43 | }
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return Scaffold(
48 | appBar: AppBar(
49 | title: Text('JavaScriptCore for Flutter'),
50 | ),
51 | body: TextField(
52 | maxLines: 50,
53 | decoration: InputDecoration(
54 | border: InputBorder.none,
55 | ),
56 | controller: _jsInputController,
57 | ),
58 | floatingActionButton: FloatingActionButton(
59 | onPressed: () {
60 | showDialog(
61 | context: context,
62 | builder: (context) {
63 | return AlertDialog(
64 | title: Text('Result'),
65 | content: Text(_runJs(_jsInputController.text)),
66 | );
67 | },
68 | );
69 | },
70 | child: Icon(Icons.autorenew),
71 | ),
72 | );
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_jscore_example/views/h2dart_page.dart';
3 | import 'package:flutter_jscore_example/views/bindings_page.dart';
4 | import 'package:flutter_jscore_example/views/jscore_page.dart';
5 |
6 | void main() => runApp(MyApp());
7 |
8 | class MyApp extends StatefulWidget {
9 | @override
10 | _MyAppState createState() => _MyAppState();
11 | }
12 |
13 | class _MyAppState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | title: 'flutter_jscore',
18 | home: FlutterJsCorePage(),
19 | );
20 | }
21 | }
22 |
23 | class FlutterJsCorePage extends StatelessWidget {
24 | @override
25 | Widget build(BuildContext context) {
26 | return Scaffold(
27 | appBar: AppBar(
28 | title: Text('JavaScriptCore for Flutter'),
29 | ),
30 | body: ListView(
31 | children: [
32 | ListTile(
33 | title: Text('H2Dart tool'),
34 | subtitle: Text('C .h file to dart file'),
35 | onTap: () {
36 | Navigator.of(context).push(MaterialPageRoute(builder: (context) {
37 | return H2DartPage();
38 | }));
39 | },
40 | ),
41 | Divider(
42 | height: 0.5,
43 | thickness: 0.5,
44 | ),
45 | ListTile(
46 | title: Text('Bindings page'),
47 | subtitle: Text('Dart binding C'),
48 | onTap: () {
49 | Navigator.of(context).push(MaterialPageRoute(builder: (context) {
50 | return BindingsPage();
51 | }));
52 | },
53 | ),
54 | Divider(
55 | height: 0.5,
56 | thickness: 0.5,
57 | ),
58 | ListTile(
59 | title: Text('JsCore page'),
60 | subtitle: Text('Use flutter_jscore lib'),
61 | onTap: () {
62 | Navigator.of(context).push(MaterialPageRoute(builder: (context) {
63 | return JsCorePage();
64 | }));
65 | },
66 | ),
67 | ],
68 | ),
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/example/lib/views/h2dart_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_jscore_example/utils/h2dart.dart';
3 |
4 | /// 头文件转dart
5 | class H2DartPage extends StatefulWidget {
6 | @override
7 | State createState() {
8 | return H2DartPageState();
9 | }
10 | }
11 |
12 | class H2DartPageState extends State {
13 | late TextEditingController _hController;
14 | late TextEditingController _dartController;
15 |
16 | @override
17 | void initState() {
18 | _hController = TextEditingController();
19 | _dartController = TextEditingController();
20 | super.initState();
21 | }
22 |
23 | @override
24 | void dispose() {
25 | _hController.dispose();
26 | _dartController.dispose();
27 | super.dispose();
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: Text('.h to .dart'),
35 | actions: [
36 | IconButton(
37 | icon: Icon(Icons.autorenew),
38 | onPressed: () {
39 | _dartController.text = h2Dart(_hController.text);
40 | },
41 | ),
42 | ],
43 | ),
44 | body: ListView(
45 | children: [
46 | Text('.h'),
47 | TextField(
48 | controller: _hController,
49 | maxLines: 20,
50 | style: TextStyle(
51 | fontSize: 10.0,
52 | ),
53 | ),
54 | Text('.dart'),
55 | TextField(
56 | controller: _dartController,
57 | maxLines: 20,
58 | style: TextStyle(
59 | fontSize: 10.0,
60 | ),
61 | ),
62 | ],
63 | ),
64 | );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/lib/views/jscore_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | import 'package:flutter_jscore/flutter_jscore.dart';
6 |
7 | class JsCorePage extends StatefulWidget {
8 | @override
9 | State createState() {
10 | return JsCorePageState();
11 | }
12 | }
13 |
14 | class JsCorePageState extends State {
15 | // 输入控制器
16 | late TextEditingController _jsInputController;
17 |
18 | // 结果
19 | String? _result;
20 |
21 | // Jsc上下文
22 | late JSContext _jsContext;
23 |
24 | @override
25 | void initState() {
26 | super.initState();
27 | // 创建js上下文
28 | _jsContext = JSContext.createInGroup();
29 | // 注册alert方法
30 | _alertDartFunc = _alert;
31 | var jsAlertFunction = JSObject.makeFunctionWithCallback(
32 | _jsContext, 'alert', Pointer.fromFunction(alert));
33 | _jsContext.globalObject.setProperty('alert', jsAlertFunction.toValue(),
34 | JSPropertyAttributes.kJSPropertyAttributeNone);
35 | // 注册flutter.print静态方法
36 | _printDartFunc = _print;
37 | var flutterJSClass = JSClass.create(JSClassDefinition(
38 | version: 0,
39 | attributes: JSClassAttributes.kJSClassAttributeNone,
40 | className: 'flutter',
41 | staticFunctions: [
42 | JSStaticFunction(
43 | name: 'print',
44 | callAsFunction: Pointer.fromFunction(flutterPrint),
45 | attributes: JSPropertyAttributes.kJSPropertyAttributeNone,
46 | ),
47 | ],
48 | ));
49 | var flutterJSObject = JSObject.make(_jsContext, flutterJSClass);
50 | _jsContext.globalObject.setProperty('flutter', flutterJSObject.toValue(),
51 | JSPropertyAttributes.kJSPropertyAttributeDontDelete);
52 | // 设置默认JavaScript脚本
53 | _jsInputController = TextEditingController(text: '''
54 | function helloJsCore()
55 | {
56 | var years = 2000 + 20;
57 | alert('Hello JavaScriptCore!', years);
58 | flutter.print('Hello JavaScriptCore!');
59 | return 'JSCore' + (2000 + 20);
60 | }
61 | helloJsCore();
62 | ''');
63 | }
64 |
65 | @override
66 | void dispose() {
67 | _jsInputController.dispose();
68 | // 释放js上下文
69 | _jsContext.release();
70 | super.dispose();
71 | }
72 |
73 | /// 绑定JavaScript alert()函数
74 | static Pointer alert(
75 | Pointer ctx,
76 | Pointer function,
77 | Pointer thisObject,
78 | int argumentCount,
79 | Pointer arguments,
80 | Pointer exception) {
81 | if (_alertDartFunc != null) {
82 | _alertDartFunc!(
83 | ctx, function, thisObject, argumentCount, arguments, exception);
84 | }
85 | return nullptr;
86 | }
87 |
88 | static JSObjectCallAsFunctionCallbackDart? _alertDartFunc;
89 | Pointer _alert(
90 | Pointer ctx,
91 | Pointer function,
92 | Pointer thisObject,
93 | int argumentCount,
94 | Pointer arguments,
95 | Pointer exception) {
96 | String msg = 'No Message';
97 | if (argumentCount != 0) {
98 | msg = '';
99 | for (int i = 0; i < argumentCount; i++) {
100 | if (i != 0) {
101 | msg += '\n';
102 | }
103 | var jsValueRef = arguments[i];
104 | msg += JSValue(_jsContext, jsValueRef).string!;
105 | }
106 | }
107 | showDialog(
108 | context: context,
109 | builder: (context) {
110 | return AlertDialog(
111 | title: Text('Alert'),
112 | content: Text(msg),
113 | );
114 | });
115 | return nullptr;
116 | }
117 |
118 | /// 绑定flutter.print()函数
119 | static Pointer flutterPrint(
120 | Pointer ctx,
121 | Pointer function,
122 | Pointer thisObject,
123 | int argumentCount,
124 | Pointer arguments,
125 | Pointer exception) {
126 | if (_printDartFunc != null) {
127 | _printDartFunc!(
128 | ctx, function, thisObject, argumentCount, arguments, exception);
129 | }
130 | return nullptr;
131 | }
132 |
133 | static JSObjectCallAsFunctionCallbackDart? _printDartFunc;
134 | Pointer _print(
135 | Pointer ctx,
136 | Pointer function,
137 | Pointer thisObject,
138 | int argumentCount,
139 | Pointer arguments,
140 | Pointer exception) {
141 | if (argumentCount > 0) {
142 | print(JSValue(_jsContext, arguments[0]).string);
143 | }
144 | return nullptr;
145 | }
146 |
147 | // 运行JavaScript脚本
148 | String? _runJs(String script) {
149 | // 运行JavaScript脚本
150 | var jsValue = _jsContext.evaluate(script);
151 | // 获取返回结果
152 | return jsValue.string;
153 | }
154 |
155 | @override
156 | Widget build(BuildContext context) {
157 | return Scaffold(
158 | appBar: AppBar(
159 | title: Text('JavaScriptCore for Flutter'),
160 | ),
161 | body: ListView(
162 | padding: EdgeInsets.only(top: 10.0),
163 | children: [
164 | Container(
165 | margin: EdgeInsets.only(left: 10.0, right: 10.0),
166 | child: Text('JavaScript:'),
167 | ),
168 | Container(
169 | margin: EdgeInsets.all(10.0),
170 | padding: EdgeInsets.all(5.0),
171 | decoration: BoxDecoration(
172 | border:
173 | Border.all(width: 1.0, color: Theme.of(context).primaryColor),
174 | borderRadius: BorderRadius.all(new Radius.circular(5.0)),
175 | ),
176 | child: TextField(
177 | controller: _jsInputController,
178 | maxLines: 30,
179 | style: TextStyle(
180 | fontSize: 12.0,
181 | ),
182 | decoration: InputDecoration(
183 | border: InputBorder.none,
184 | ),
185 | ),
186 | ),
187 | Container(
188 | margin: EdgeInsets.only(left: 10.0, right: 10.0),
189 | child: Text('Result: ${_result ?? ''}'),
190 | ),
191 | ],
192 | ),
193 | floatingActionButton: FloatingActionButton(
194 | onPressed: () {
195 | setState(() {
196 | _result = _runJs(_jsInputController.text);
197 | });
198 | },
199 | child: Icon(Icons.autorenew),
200 | ),
201 | );
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/example/linux/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral
2 |
--------------------------------------------------------------------------------
/example/linux/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 | project(runner LANGUAGES CXX)
3 |
4 | set(BINARY_NAME "flutter_jscore_example")
5 | set(APPLICATION_ID "com.knoyo.flutter_jscore")
6 |
7 | cmake_policy(SET CMP0063 NEW)
8 |
9 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
10 |
11 | # Root filesystem for cross-building.
12 | if(FLUTTER_TARGET_PLATFORM_SYSROOT)
13 | set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
14 | set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
15 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
16 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
17 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
18 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
19 | endif()
20 |
21 | # Configure build options.
22 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
23 | set(CMAKE_BUILD_TYPE "Debug" CACHE
24 | STRING "Flutter build mode" FORCE)
25 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
26 | "Debug" "Profile" "Release")
27 | endif()
28 |
29 | # Compilation settings that should be applied to most targets.
30 | function(APPLY_STANDARD_SETTINGS TARGET)
31 | target_compile_features(${TARGET} PUBLIC cxx_std_14)
32 | target_compile_options(${TARGET} PRIVATE -Wall -Werror)
33 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>")
34 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>")
35 | endfunction()
36 |
37 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
38 |
39 | # Flutter library and tool build rules.
40 | add_subdirectory(${FLUTTER_MANAGED_DIR})
41 |
42 | # System-level dependencies.
43 | find_package(PkgConfig REQUIRED)
44 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
45 |
46 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
47 |
48 | # Application build
49 | add_executable(${BINARY_NAME}
50 | "main.cc"
51 | "my_application.cc"
52 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
53 | )
54 | apply_standard_settings(${BINARY_NAME})
55 | target_link_libraries(${BINARY_NAME} PRIVATE flutter)
56 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
57 | add_dependencies(${BINARY_NAME} flutter_assemble)
58 | # Only the install-generated bundle's copy of the executable will launch
59 | # correctly, since the resources must in the right relative locations. To avoid
60 | # people trying to run the unbundled copy, put it in a subdirectory instead of
61 | # the default top-level location.
62 | set_target_properties(${BINARY_NAME}
63 | PROPERTIES
64 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
65 | )
66 |
67 | # Generated plugin build rules, which manage building the plugins and adding
68 | # them to the application.
69 | include(flutter/generated_plugins.cmake)
70 |
71 |
72 | # === Installation ===
73 | # By default, "installing" just makes a relocatable bundle in the build
74 | # directory.
75 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
76 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
77 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
78 | endif()
79 |
80 | # Start with a clean build bundle directory every time.
81 | install(CODE "
82 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
83 | " COMPONENT Runtime)
84 |
85 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
86 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
87 |
88 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
89 | COMPONENT Runtime)
90 |
91 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
92 | COMPONENT Runtime)
93 |
94 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
95 | COMPONENT Runtime)
96 |
97 | if(PLUGIN_BUNDLED_LIBRARIES)
98 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
99 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
100 | COMPONENT Runtime)
101 | endif()
102 |
103 | # Fully re-copy the assets directory on each build to avoid having stale files
104 | # from a previous install.
105 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
106 | install(CODE "
107 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
108 | " COMPONENT Runtime)
109 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
110 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
111 |
112 | # Install the AOT library on non-Debug builds only.
113 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
114 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
115 | COMPONENT Runtime)
116 | endif()
117 |
--------------------------------------------------------------------------------
/example/linux/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
4 |
5 | # Configuration provided via flutter tool.
6 | include(${EPHEMERAL_DIR}/generated_config.cmake)
7 |
8 | # TODO: Move the rest of this into files in ephemeral. See
9 | # https://github.com/flutter/flutter/issues/57146.
10 |
11 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...),
12 | # which isn't available in 3.10.
13 | function(list_prepend LIST_NAME PREFIX)
14 | set(NEW_LIST "")
15 | foreach(element ${${LIST_NAME}})
16 | list(APPEND NEW_LIST "${PREFIX}${element}")
17 | endforeach(element)
18 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
19 | endfunction()
20 |
21 | # === Flutter Library ===
22 | # System-level dependencies.
23 | find_package(PkgConfig REQUIRED)
24 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
25 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
26 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
27 |
28 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
29 |
30 | # Published to parent scope for install step.
31 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
32 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
33 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
34 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
35 |
36 | list(APPEND FLUTTER_LIBRARY_HEADERS
37 | "fl_basic_message_channel.h"
38 | "fl_binary_codec.h"
39 | "fl_binary_messenger.h"
40 | "fl_dart_project.h"
41 | "fl_engine.h"
42 | "fl_json_message_codec.h"
43 | "fl_json_method_codec.h"
44 | "fl_message_codec.h"
45 | "fl_method_call.h"
46 | "fl_method_channel.h"
47 | "fl_method_codec.h"
48 | "fl_method_response.h"
49 | "fl_plugin_registrar.h"
50 | "fl_plugin_registry.h"
51 | "fl_standard_message_codec.h"
52 | "fl_standard_method_codec.h"
53 | "fl_string_codec.h"
54 | "fl_value.h"
55 | "fl_view.h"
56 | "flutter_linux.h"
57 | )
58 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
59 | add_library(flutter INTERFACE)
60 | target_include_directories(flutter INTERFACE
61 | "${EPHEMERAL_DIR}"
62 | )
63 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
64 | target_link_libraries(flutter INTERFACE
65 | PkgConfig::GTK
66 | PkgConfig::GLIB
67 | PkgConfig::GIO
68 | )
69 | add_dependencies(flutter flutter_assemble)
70 |
71 | # === Flutter tool backend ===
72 | # _phony_ is a non-existent file to force this command to run every time,
73 | # since currently there's no way to get a full input/output list from the
74 | # flutter tool.
75 | add_custom_command(
76 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
77 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_
78 | COMMAND ${CMAKE_COMMAND} -E env
79 | ${FLUTTER_TOOL_ENVIRONMENT}
80 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
81 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
82 | VERBATIM
83 | )
84 | add_custom_target(flutter_assemble DEPENDS
85 | "${FLUTTER_LIBRARY}"
86 | ${FLUTTER_LIBRARY_HEADERS}
87 | )
88 |
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #include "generated_plugin_registrant.h"
6 |
7 | #include
8 |
9 | void fl_register_plugins(FlPluginRegistry* registry) {
10 | g_autoptr(FlPluginRegistrar) flutter_jscore_registrar =
11 | fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterJscorePlugin");
12 | flutter_jscore_plugin_register_with_registrar(flutter_jscore_registrar);
13 | }
14 |
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GENERATED_PLUGIN_REGISTRANT_
6 | #define GENERATED_PLUGIN_REGISTRANT_
7 |
8 | #include
9 |
10 | // Registers Flutter plugins.
11 | void fl_register_plugins(FlPluginRegistry* registry);
12 |
13 | #endif // GENERATED_PLUGIN_REGISTRANT_
14 |
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | flutter_jscore
7 | )
8 |
9 | set(PLUGIN_BUNDLED_LIBRARIES)
10 |
11 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
16 | endforeach(plugin)
17 |
--------------------------------------------------------------------------------
/example/linux/main.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | int main(int argc, char** argv) {
4 | g_autoptr(MyApplication) app = my_application_new();
5 | return g_application_run(G_APPLICATION(app), argc, argv);
6 | }
7 |
--------------------------------------------------------------------------------
/example/linux/my_application.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | #include
4 | #ifdef GDK_WINDOWING_X11
5 | #include
6 | #endif
7 |
8 | #include "flutter/generated_plugin_registrant.h"
9 |
10 | struct _MyApplication {
11 | GtkApplication parent_instance;
12 | char** dart_entrypoint_arguments;
13 | };
14 |
15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
16 |
17 | // Implements GApplication::activate.
18 | static void my_application_activate(GApplication* application) {
19 | MyApplication* self = MY_APPLICATION(application);
20 | GtkWindow* window =
21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
22 |
23 | // Use a header bar when running in GNOME as this is the common style used
24 | // by applications and is the setup most users will be using (e.g. Ubuntu
25 | // desktop).
26 | // If running on X and not using GNOME then just use a traditional title bar
27 | // in case the window manager does more exotic layout, e.g. tiling.
28 | // If running on Wayland assume the header bar will work (may need changing
29 | // if future cases occur).
30 | gboolean use_header_bar = TRUE;
31 | #ifdef GDK_WINDOWING_X11
32 | GdkScreen *screen = gtk_window_get_screen(window);
33 | if (GDK_IS_X11_SCREEN(screen)) {
34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
36 | use_header_bar = FALSE;
37 | }
38 | }
39 | #endif
40 | if (use_header_bar) {
41 | GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42 | gtk_widget_show(GTK_WIDGET(header_bar));
43 | gtk_header_bar_set_title(header_bar, "flutter_jscore_example");
44 | gtk_header_bar_set_show_close_button(header_bar, TRUE);
45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46 | }
47 | else {
48 | gtk_window_set_title(window, "flutter_jscore_example");
49 | }
50 |
51 | gtk_window_set_default_size(window, 1280, 720);
52 | gtk_widget_show(GTK_WIDGET(window));
53 |
54 | g_autoptr(FlDartProject) project = fl_dart_project_new();
55 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
56 |
57 | FlView* view = fl_view_new(project);
58 | gtk_widget_show(GTK_WIDGET(view));
59 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
60 |
61 | fl_register_plugins(FL_PLUGIN_REGISTRY(view));
62 |
63 | gtk_widget_grab_focus(GTK_WIDGET(view));
64 | }
65 |
66 | // Implements GApplication::local_command_line.
67 | static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) {
68 | MyApplication* self = MY_APPLICATION(application);
69 | // Strip out the first argument as it is the binary name.
70 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
71 |
72 | g_autoptr(GError) error = nullptr;
73 | if (!g_application_register(application, nullptr, &error)) {
74 | g_warning("Failed to register: %s", error->message);
75 | *exit_status = 1;
76 | return TRUE;
77 | }
78 |
79 | g_application_activate(application);
80 | *exit_status = 0;
81 |
82 | return TRUE;
83 | }
84 |
85 | // Implements GObject::dispose.
86 | static void my_application_dispose(GObject *object) {
87 | MyApplication* self = MY_APPLICATION(object);
88 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
89 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
90 | }
91 |
92 | static void my_application_class_init(MyApplicationClass* klass) {
93 | G_APPLICATION_CLASS(klass)->activate = my_application_activate;
94 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
95 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
96 | }
97 |
98 | static void my_application_init(MyApplication* self) {}
99 |
100 | MyApplication* my_application_new() {
101 | return MY_APPLICATION(g_object_new(my_application_get_type(),
102 | "application-id", APPLICATION_ID,
103 | "flags", G_APPLICATION_NON_UNIQUE,
104 | nullptr));
105 | }
106 |
--------------------------------------------------------------------------------
/example/linux/my_application.h:
--------------------------------------------------------------------------------
1 | #ifndef FLUTTER_MY_APPLICATION_H_
2 | #define FLUTTER_MY_APPLICATION_H_
3 |
4 | #include
5 |
6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
7 | GtkApplication)
8 |
9 | /**
10 | * my_application_new:
11 | *
12 | * Creates a new Flutter-based application.
13 | *
14 | * Returns: a new #MyApplication.
15 | */
16 | MyApplication* my_application_new();
17 |
18 | #endif // FLUTTER_MY_APPLICATION_H_
19 |
--------------------------------------------------------------------------------
/example/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/xcuserdata/
7 |
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 | import flutter_jscore
9 |
10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
11 | FlutterJscorePlugin.register(with: registry.registrar(forPlugin: "FlutterJscorePlugin"))
12 | }
13 |
--------------------------------------------------------------------------------
/example/macos/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx, '10.11'
2 |
3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5 |
6 | project 'Runner', {
7 | 'Debug' => :debug,
8 | 'Profile' => :release,
9 | 'Release' => :release,
10 | }
11 |
12 | def flutter_root
13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14 | unless File.exist?(generated_xcode_build_settings_path)
15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16 | end
17 |
18 | File.foreach(generated_xcode_build_settings_path) do |line|
19 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
20 | return matches[1].strip if matches
21 | end
22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23 | end
24 |
25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26 |
27 | flutter_macos_podfile_setup
28 |
29 | target 'Runner' do
30 | use_frameworks!
31 | use_modular_headers!
32 |
33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
34 | end
35 |
36 | post_install do |installer|
37 | installer.pods_project.targets.each do |target|
38 | flutter_additional_macos_build_settings(target)
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/example/macos/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - flutter_jscore (0.0.1):
3 | - FlutterMacOS
4 | - FlutterMacOS (1.0.0)
5 |
6 | DEPENDENCIES:
7 | - flutter_jscore (from `Flutter/ephemeral/.symlinks/plugins/flutter_jscore/macos`)
8 | - FlutterMacOS (from `Flutter/ephemeral`)
9 |
10 | EXTERNAL SOURCES:
11 | flutter_jscore:
12 | :path: Flutter/ephemeral/.symlinks/plugins/flutter_jscore/macos
13 | FlutterMacOS:
14 | :path: Flutter/ephemeral
15 |
16 | SPEC CHECKSUMS:
17 | flutter_jscore: ae246c4eb17e943b06adc3ab1cdd41ddf8e68bb2
18 | FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424
19 |
20 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
21 |
22 | COCOAPODS: 1.10.0
23 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @NSApplicationMain
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = flutter_jscore_example
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.knoyo.flutterJscore
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2020 com.knoyo. All rights reserved.
15 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/example/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/example/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController.init()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "2.6.1"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.1.0"
18 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.1.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.2.0"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.1.0"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.15.0"
46 | cupertino_icons:
47 | dependency: "direct main"
48 | description:
49 | name: cupertino_icons
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "0.1.3"
53 | fake_async:
54 | dependency: transitive
55 | description:
56 | name: fake_async
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "1.2.0"
60 | ffi:
61 | dependency: transitive
62 | description:
63 | name: ffi
64 | url: "https://pub.flutter-io.cn"
65 | source: hosted
66 | version: "1.0.0"
67 | flutter:
68 | dependency: "direct main"
69 | description: flutter
70 | source: sdk
71 | version: "0.0.0"
72 | flutter_jscore:
73 | dependency: "direct dev"
74 | description:
75 | path: ".."
76 | relative: true
77 | source: path
78 | version: "1.0.0"
79 | flutter_test:
80 | dependency: "direct dev"
81 | description: flutter
82 | source: sdk
83 | version: "0.0.0"
84 | matcher:
85 | dependency: transitive
86 | description:
87 | name: matcher
88 | url: "https://pub.flutter-io.cn"
89 | source: hosted
90 | version: "0.12.10"
91 | meta:
92 | dependency: transitive
93 | description:
94 | name: meta
95 | url: "https://pub.flutter-io.cn"
96 | source: hosted
97 | version: "1.3.0"
98 | path:
99 | dependency: transitive
100 | description:
101 | name: path
102 | url: "https://pub.flutter-io.cn"
103 | source: hosted
104 | version: "1.8.0"
105 | sky_engine:
106 | dependency: transitive
107 | description: flutter
108 | source: sdk
109 | version: "0.0.99"
110 | source_span:
111 | dependency: transitive
112 | description:
113 | name: source_span
114 | url: "https://pub.flutter-io.cn"
115 | source: hosted
116 | version: "1.8.1"
117 | stack_trace:
118 | dependency: transitive
119 | description:
120 | name: stack_trace
121 | url: "https://pub.flutter-io.cn"
122 | source: hosted
123 | version: "1.10.0"
124 | stream_channel:
125 | dependency: transitive
126 | description:
127 | name: stream_channel
128 | url: "https://pub.flutter-io.cn"
129 | source: hosted
130 | version: "2.1.0"
131 | string_scanner:
132 | dependency: transitive
133 | description:
134 | name: string_scanner
135 | url: "https://pub.flutter-io.cn"
136 | source: hosted
137 | version: "1.1.0"
138 | term_glyph:
139 | dependency: transitive
140 | description:
141 | name: term_glyph
142 | url: "https://pub.flutter-io.cn"
143 | source: hosted
144 | version: "1.2.0"
145 | test_api:
146 | dependency: transitive
147 | description:
148 | name: test_api
149 | url: "https://pub.flutter-io.cn"
150 | source: hosted
151 | version: "0.3.0"
152 | typed_data:
153 | dependency: transitive
154 | description:
155 | name: typed_data
156 | url: "https://pub.flutter-io.cn"
157 | source: hosted
158 | version: "1.3.0"
159 | vector_math:
160 | dependency: transitive
161 | description:
162 | name: vector_math
163 | url: "https://pub.flutter-io.cn"
164 | source: hosted
165 | version: "2.1.0"
166 | sdks:
167 | dart: ">=2.12.0 <3.0.0"
168 | flutter: ">=1.24.0"
169 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_jscore_example
2 | description: Demonstrates how to use the flutter_jscore plugin.
3 | publish_to: 'none'
4 | version: '1.0.0'
5 |
6 | environment:
7 | sdk: ">=2.12.0 <3.0.0"
8 | flutter: ">=1.24.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | # The following adds the Cupertino Icons font to your application.
15 | # Use with the CupertinoIcons class for iOS style icons.
16 | cupertino_icons: ^0.1.2
17 |
18 | dev_dependencies:
19 | flutter_test:
20 | sdk: flutter
21 |
22 | flutter_jscore:
23 | path: ../
24 |
25 | # For information on the generic Dart part of this file, see the
26 | # following page: https://dart.dev/tools/pub/pubspec
27 |
28 | # The following section is specific to Flutter.
29 | flutter:
30 |
31 | # The following line ensures that the Material Icons font is
32 | # included with your application, so that you can use the icons in
33 | # the material Icons class.
34 | uses-material-design: true
35 |
36 | # To add assets to your application, add an assets section, like this:
37 | # assets:
38 | # - images/a_dot_burr.jpeg
39 | # - images/a_dot_ham.jpeg
40 |
41 | # An image asset can refer to one or more resolution-specific "variants", see
42 | # https://flutter.dev/assets-and-images/#resolution-aware.
43 |
44 | # For details regarding adding assets from package dependencies, see
45 | # https://flutter.dev/assets-and-images/#from-packages
46 |
47 | # To add custom fonts to your application, add a fonts section here,
48 | # in this "flutter" section. Each entry in this list should have a
49 | # "family" key with the font family name, and a "fonts" key with a
50 | # list giving the asset and other descriptors for the font. For
51 | # example:
52 | # fonts:
53 | # - family: Schyler
54 | # fonts:
55 | # - asset: fonts/Schyler-Regular.ttf
56 | # - asset: fonts/Schyler-Italic.ttf
57 | # style: italic
58 | # - family: Trajan Pro
59 | # fonts:
60 | # - asset: fonts/TrajanPro.ttf
61 | # - asset: fonts/TrajanPro_Bold.ttf
62 | # weight: 700
63 | #
64 | # For details regarding fonts from package dependencies,
65 | # see https://flutter.dev/custom-fonts/#from-packages
66 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_jscore_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) =>
22 | widget is Text && widget.data!.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/example/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/web/favicon.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | flutter_jscore_example
18 |
19 |
20 |
21 |
24 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flutter_jscore_example",
3 | "short_name": "flutter_jscore_example",
4 | "start_url": ".",
5 | "display": "minimal-ui",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "Demonstrates how to use the flutter_jscore plugin.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/example/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/example/windows/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(flutter_jscore_example LANGUAGES CXX)
3 |
4 | set(BINARY_NAME "flutter_jscore_example")
5 |
6 | cmake_policy(SET CMP0063 NEW)
7 |
8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
9 |
10 | # Configure build options.
11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
12 | if(IS_MULTICONFIG)
13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
14 | CACHE STRING "" FORCE)
15 | else()
16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
17 | set(CMAKE_BUILD_TYPE "Debug" CACHE
18 | STRING "Flutter build mode" FORCE)
19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
20 | "Debug" "Profile" "Release")
21 | endif()
22 | endif()
23 |
24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
28 |
29 | # Use Unicode for all projects.
30 | add_definitions(-DUNICODE -D_UNICODE)
31 |
32 | # Compilation settings that should be applied to most targets.
33 | function(APPLY_STANDARD_SETTINGS TARGET)
34 | target_compile_features(${TARGET} PUBLIC cxx_std_17)
35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
36 | target_compile_options(${TARGET} PRIVATE /EHsc)
37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>")
39 | endfunction()
40 |
41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
42 |
43 | # Flutter library and tool build rules.
44 | add_subdirectory(${FLUTTER_MANAGED_DIR})
45 |
46 | # Application build
47 | add_subdirectory("runner")
48 |
49 | # Generated plugin build rules, which manage building the plugins and adding
50 | # them to the application.
51 | include(flutter/generated_plugins.cmake)
52 |
53 |
54 | # === Installation ===
55 | # Support files are copied into place next to the executable, so that it can
56 | # run in place. This is done instead of making a separate bundle (as on Linux)
57 | # so that building and running from within Visual Studio will work.
58 | set(BUILD_BUNDLE_DIR "$")
59 | # Make the "install" step default, as it's required to run.
60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
63 | endif()
64 |
65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
67 |
68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
69 | COMPONENT Runtime)
70 |
71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
72 | COMPONENT Runtime)
73 |
74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
75 | COMPONENT Runtime)
76 |
77 | if(PLUGIN_BUNDLED_LIBRARIES)
78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
80 | COMPONENT Runtime)
81 | endif()
82 |
83 | # Add JavaScriptCore libs
84 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/JavaScriptCore/"
85 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
86 | COMPONENT Runtime)
87 |
88 | # Fully re-copy the assets directory on each build to avoid having stale files
89 | # from a previous install.
90 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
91 | install(CODE "
92 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
93 | " COMPONENT Runtime)
94 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
95 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
96 |
97 | # Install the AOT library on non-Debug builds only.
98 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
99 | CONFIGURATIONS Profile;Release
100 | COMPONENT Runtime)
101 |
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/ASL.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/ASL.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/CoreFoundation.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/CoreFoundation.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/JavaScriptCore.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/JavaScriptCore.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/WTF.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/WTF.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/icudt62.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/icudt62.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/libdispatch.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/libdispatch.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/libicuin.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/libicuin.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/libicuuc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/libicuuc.dll
--------------------------------------------------------------------------------
/example/windows/JavaScriptCore/objc.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/JavaScriptCore/objc.dll
--------------------------------------------------------------------------------
/example/windows/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 |
3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
4 |
5 | # Configuration provided via flutter tool.
6 | include(${EPHEMERAL_DIR}/generated_config.cmake)
7 |
8 | # TODO: Move the rest of this into files in ephemeral. See
9 | # https://github.com/flutter/flutter/issues/57146.
10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
11 |
12 | # === Flutter Library ===
13 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
14 |
15 | # Published to parent scope for install step.
16 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
17 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
18 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
19 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
20 |
21 | list(APPEND FLUTTER_LIBRARY_HEADERS
22 | "flutter_export.h"
23 | "flutter_windows.h"
24 | "flutter_messenger.h"
25 | "flutter_plugin_registrar.h"
26 | "flutter_texture_registrar.h"
27 | )
28 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
29 | add_library(flutter INTERFACE)
30 | target_include_directories(flutter INTERFACE
31 | "${EPHEMERAL_DIR}"
32 | )
33 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
34 | add_dependencies(flutter flutter_assemble)
35 |
36 | # === Wrapper ===
37 | list(APPEND CPP_WRAPPER_SOURCES_CORE
38 | "core_implementations.cc"
39 | "standard_codec.cc"
40 | )
41 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
42 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
43 | "plugin_registrar.cc"
44 | )
45 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
46 | list(APPEND CPP_WRAPPER_SOURCES_APP
47 | "flutter_engine.cc"
48 | "flutter_view_controller.cc"
49 | )
50 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
51 |
52 | # Wrapper sources needed for a plugin.
53 | add_library(flutter_wrapper_plugin STATIC
54 | ${CPP_WRAPPER_SOURCES_CORE}
55 | ${CPP_WRAPPER_SOURCES_PLUGIN}
56 | )
57 | apply_standard_settings(flutter_wrapper_plugin)
58 | set_target_properties(flutter_wrapper_plugin PROPERTIES
59 | POSITION_INDEPENDENT_CODE ON)
60 | set_target_properties(flutter_wrapper_plugin PROPERTIES
61 | CXX_VISIBILITY_PRESET hidden)
62 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
63 | target_include_directories(flutter_wrapper_plugin PUBLIC
64 | "${WRAPPER_ROOT}/include"
65 | )
66 | add_dependencies(flutter_wrapper_plugin flutter_assemble)
67 |
68 | # Wrapper sources needed for the runner.
69 | add_library(flutter_wrapper_app STATIC
70 | ${CPP_WRAPPER_SOURCES_CORE}
71 | ${CPP_WRAPPER_SOURCES_APP}
72 | )
73 | apply_standard_settings(flutter_wrapper_app)
74 | target_link_libraries(flutter_wrapper_app PUBLIC flutter)
75 | target_include_directories(flutter_wrapper_app PUBLIC
76 | "${WRAPPER_ROOT}/include"
77 | )
78 | add_dependencies(flutter_wrapper_app flutter_assemble)
79 |
80 | # === Flutter tool backend ===
81 | # _phony_ is a non-existent file to force this command to run every time,
82 | # since currently there's no way to get a full input/output list from the
83 | # flutter tool.
84 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
85 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
86 | add_custom_command(
87 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
88 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
89 | ${CPP_WRAPPER_SOURCES_APP}
90 | ${PHONY_OUTPUT}
91 | COMMAND ${CMAKE_COMMAND} -E env
92 | ${FLUTTER_TOOL_ENVIRONMENT}
93 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
94 | windows-x64 $
95 | VERBATIM
96 | )
97 | add_custom_target(flutter_assemble DEPENDS
98 | "${FLUTTER_LIBRARY}"
99 | ${FLUTTER_LIBRARY_HEADERS}
100 | ${CPP_WRAPPER_SOURCES_CORE}
101 | ${CPP_WRAPPER_SOURCES_PLUGIN}
102 | ${CPP_WRAPPER_SOURCES_APP}
103 | )
104 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #include "generated_plugin_registrant.h"
6 |
7 | #include
8 |
9 | void RegisterPlugins(flutter::PluginRegistry* registry) {
10 | FlutterJscorePluginRegisterWithRegistrar(
11 | registry->GetRegistrarForPlugin("FlutterJscorePlugin"));
12 | }
13 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GENERATED_PLUGIN_REGISTRANT_
6 | #define GENERATED_PLUGIN_REGISTRANT_
7 |
8 | #include
9 |
10 | // Registers Flutter plugins.
11 | void RegisterPlugins(flutter::PluginRegistry* registry);
12 |
13 | #endif // GENERATED_PLUGIN_REGISTRANT_
14 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | flutter_jscore
7 | )
8 |
9 | set(PLUGIN_BUNDLED_LIBRARIES)
10 |
11 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
16 | endforeach(plugin)
17 |
--------------------------------------------------------------------------------
/example/windows/runner/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(runner LANGUAGES CXX)
3 |
4 | add_executable(${BINARY_NAME} WIN32
5 | "flutter_window.cpp"
6 | "main.cpp"
7 | "run_loop.cpp"
8 | "utils.cpp"
9 | "win32_window.cpp"
10 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
11 | "Runner.rc"
12 | "runner.exe.manifest"
13 | )
14 | apply_standard_settings(${BINARY_NAME})
15 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
16 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
17 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
18 | add_dependencies(${BINARY_NAME} flutter_assemble)
19 |
--------------------------------------------------------------------------------
/example/windows/runner/Runner.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #pragma code_page(65001)
4 | #include "resource.h"
5 |
6 | #define APSTUDIO_READONLY_SYMBOLS
7 | /////////////////////////////////////////////////////////////////////////////
8 | //
9 | // Generated from the TEXTINCLUDE 2 resource.
10 | //
11 | #include "winres.h"
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 | #undef APSTUDIO_READONLY_SYMBOLS
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // English (United States) resources
18 |
19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""winres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "\r\n"
42 | "\0"
43 | END
44 |
45 | #endif // APSTUDIO_INVOKED
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | //
50 | // Icon
51 | //
52 |
53 | // Icon with lowest ID value placed first to ensure application icon
54 | // remains consistent on all systems.
55 | IDI_APP_ICON ICON "resources\\app_icon.ico"
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Version
61 | //
62 |
63 | #ifdef FLUTTER_BUILD_NUMBER
64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
65 | #else
66 | #define VERSION_AS_NUMBER 1,0,0
67 | #endif
68 |
69 | #ifdef FLUTTER_BUILD_NAME
70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME
71 | #else
72 | #define VERSION_AS_STRING "1.0.0"
73 | #endif
74 |
75 | VS_VERSION_INFO VERSIONINFO
76 | FILEVERSION VERSION_AS_NUMBER
77 | PRODUCTVERSION VERSION_AS_NUMBER
78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79 | #ifdef _DEBUG
80 | FILEFLAGS VS_FF_DEBUG
81 | #else
82 | FILEFLAGS 0x0L
83 | #endif
84 | FILEOS VOS__WINDOWS32
85 | FILETYPE VFT_APP
86 | FILESUBTYPE 0x0L
87 | BEGIN
88 | BLOCK "StringFileInfo"
89 | BEGIN
90 | BLOCK "040904e4"
91 | BEGIN
92 | VALUE "CompanyName", "com.knoyo" "\0"
93 | VALUE "FileDescription", "Demonstrates how to use the flutter_jscore plugin." "\0"
94 | VALUE "FileVersion", VERSION_AS_STRING "\0"
95 | VALUE "InternalName", "flutter_jscore_example" "\0"
96 | VALUE "LegalCopyright", "Copyright (C) 2021 com.knoyo. All rights reserved." "\0"
97 | VALUE "OriginalFilename", "flutter_jscore_example.exe" "\0"
98 | VALUE "ProductName", "flutter_jscore_example" "\0"
99 | VALUE "ProductVersion", VERSION_AS_STRING "\0"
100 | END
101 | END
102 | BLOCK "VarFileInfo"
103 | BEGIN
104 | VALUE "Translation", 0x409, 1252
105 | END
106 | END
107 |
108 | #endif // English (United States) resources
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 |
112 |
113 | #ifndef APSTUDIO_INVOKED
114 | /////////////////////////////////////////////////////////////////////////////
115 | //
116 | // Generated from the TEXTINCLUDE 3 resource.
117 | //
118 |
119 |
120 | /////////////////////////////////////////////////////////////////////////////
121 | #endif // not APSTUDIO_INVOKED
122 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.cpp:
--------------------------------------------------------------------------------
1 | #include "flutter_window.h"
2 |
3 | #include
4 |
5 | #include "flutter/generated_plugin_registrant.h"
6 |
7 | FlutterWindow::FlutterWindow(RunLoop* run_loop,
8 | const flutter::DartProject& project)
9 | : run_loop_(run_loop), project_(project) {}
10 |
11 | FlutterWindow::~FlutterWindow() {}
12 |
13 | bool FlutterWindow::OnCreate() {
14 | if (!Win32Window::OnCreate()) {
15 | return false;
16 | }
17 |
18 | RECT frame = GetClientArea();
19 |
20 | // The size here must match the window dimensions to avoid unnecessary surface
21 | // creation / destruction in the startup path.
22 | flutter_controller_ = std::make_unique(
23 | frame.right - frame.left, frame.bottom - frame.top, project_);
24 | // Ensure that basic setup of the controller was successful.
25 | if (!flutter_controller_->engine() || !flutter_controller_->view()) {
26 | return false;
27 | }
28 | RegisterPlugins(flutter_controller_->engine());
29 | run_loop_->RegisterFlutterInstance(flutter_controller_->engine());
30 | SetChildContent(flutter_controller_->view()->GetNativeWindow());
31 | return true;
32 | }
33 |
34 | void FlutterWindow::OnDestroy() {
35 | if (flutter_controller_) {
36 | run_loop_->UnregisterFlutterInstance(flutter_controller_->engine());
37 | flutter_controller_ = nullptr;
38 | }
39 |
40 | Win32Window::OnDestroy();
41 | }
42 |
43 | LRESULT
44 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
45 | WPARAM const wparam,
46 | LPARAM const lparam) noexcept {
47 | // Give Flutter, including plugins, an opportunity to handle window messages.
48 | if (flutter_controller_) {
49 | std::optional result =
50 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
51 | lparam);
52 | if (result) {
53 | return *result;
54 | }
55 | }
56 |
57 | switch (message) {
58 | case WM_FONTCHANGE:
59 | flutter_controller_->engine()->ReloadSystemFonts();
60 | break;
61 | }
62 |
63 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
64 | }
65 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "run_loop.h"
10 | #include "win32_window.h"
11 |
12 | // A window that does nothing but host a Flutter view.
13 | class FlutterWindow : public Win32Window {
14 | public:
15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a
16 | // Flutter view running |project|.
17 | explicit FlutterWindow(RunLoop* run_loop,
18 | const flutter::DartProject& project);
19 | virtual ~FlutterWindow();
20 |
21 | protected:
22 | // Win32Window:
23 | bool OnCreate() override;
24 | void OnDestroy() override;
25 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
26 | LPARAM const lparam) noexcept override;
27 |
28 | private:
29 | // The run loop driving events for this window.
30 | RunLoop* run_loop_;
31 |
32 | // The project to run.
33 | flutter::DartProject project_;
34 |
35 | // The Flutter instance hosted by this window.
36 | std::unique_ptr flutter_controller_;
37 | };
38 |
39 | #endif // RUNNER_FLUTTER_WINDOW_H_
40 |
--------------------------------------------------------------------------------
/example/windows/runner/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "flutter_window.h"
6 | #include "run_loop.h"
7 | #include "utils.h"
8 |
9 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
10 | _In_ wchar_t *command_line, _In_ int show_command) {
11 | // Attach to console when present (e.g., 'flutter run') or create a
12 | // new console when running with a debugger.
13 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
14 | CreateAndAttachConsole();
15 | }
16 |
17 | // Initialize COM, so that it is available for use in the library and/or
18 | // plugins.
19 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
20 |
21 | RunLoop run_loop;
22 |
23 | flutter::DartProject project(L"data");
24 |
25 | std::vector command_line_arguments =
26 | GetCommandLineArguments();
27 |
28 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
29 |
30 | FlutterWindow window(&run_loop, project);
31 | Win32Window::Point origin(10, 10);
32 | Win32Window::Size size(1280, 720);
33 | if (!window.CreateAndShow(L"flutter_jscore_example", origin, size)) {
34 | return EXIT_FAILURE;
35 | }
36 | window.SetQuitOnClose(true);
37 |
38 | run_loop.Run();
39 |
40 | ::CoUninitialize();
41 | return EXIT_SUCCESS;
42 | }
43 |
--------------------------------------------------------------------------------
/example/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/example/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/example/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/example/windows/runner/run_loop.cpp:
--------------------------------------------------------------------------------
1 | #include "run_loop.h"
2 |
3 | #include
4 |
5 | #include
6 |
7 | RunLoop::RunLoop() {}
8 |
9 | RunLoop::~RunLoop() {}
10 |
11 | void RunLoop::Run() {
12 | bool keep_running = true;
13 | TimePoint next_flutter_event_time = TimePoint::clock::now();
14 | while (keep_running) {
15 | std::chrono::nanoseconds wait_duration =
16 | std::max(std::chrono::nanoseconds(0),
17 | next_flutter_event_time - TimePoint::clock::now());
18 | ::MsgWaitForMultipleObjects(
19 | 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000),
20 | QS_ALLINPUT);
21 | bool processed_events = false;
22 | MSG message;
23 | // All pending Windows messages must be processed; MsgWaitForMultipleObjects
24 | // won't return again for items left in the queue after PeekMessage.
25 | while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) {
26 | processed_events = true;
27 | if (message.message == WM_QUIT) {
28 | keep_running = false;
29 | break;
30 | }
31 | ::TranslateMessage(&message);
32 | ::DispatchMessage(&message);
33 | // Allow Flutter to process messages each time a Windows message is
34 | // processed, to prevent starvation.
35 | next_flutter_event_time =
36 | std::min(next_flutter_event_time, ProcessFlutterMessages());
37 | }
38 | // If the PeekMessage loop didn't run, process Flutter messages.
39 | if (!processed_events) {
40 | next_flutter_event_time =
41 | std::min(next_flutter_event_time, ProcessFlutterMessages());
42 | }
43 | }
44 | }
45 |
46 | void RunLoop::RegisterFlutterInstance(
47 | flutter::FlutterEngine* flutter_instance) {
48 | flutter_instances_.insert(flutter_instance);
49 | }
50 |
51 | void RunLoop::UnregisterFlutterInstance(
52 | flutter::FlutterEngine* flutter_instance) {
53 | flutter_instances_.erase(flutter_instance);
54 | }
55 |
56 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() {
57 | TimePoint next_event_time = TimePoint::max();
58 | for (auto instance : flutter_instances_) {
59 | std::chrono::nanoseconds wait_duration = instance->ProcessMessages();
60 | if (wait_duration != std::chrono::nanoseconds::max()) {
61 | next_event_time =
62 | std::min(next_event_time, TimePoint::clock::now() + wait_duration);
63 | }
64 | }
65 | return next_event_time;
66 | }
67 |
--------------------------------------------------------------------------------
/example/windows/runner/run_loop.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_RUN_LOOP_H_
2 | #define RUNNER_RUN_LOOP_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | // A runloop that will service events for Flutter instances as well
10 | // as native messages.
11 | class RunLoop {
12 | public:
13 | RunLoop();
14 | ~RunLoop();
15 |
16 | // Prevent copying
17 | RunLoop(RunLoop const&) = delete;
18 | RunLoop& operator=(RunLoop const&) = delete;
19 |
20 | // Runs the run loop until the application quits.
21 | void Run();
22 |
23 | // Registers the given Flutter instance for event servicing.
24 | void RegisterFlutterInstance(
25 | flutter::FlutterEngine* flutter_instance);
26 |
27 | // Unregisters the given Flutter instance from event servicing.
28 | void UnregisterFlutterInstance(
29 | flutter::FlutterEngine* flutter_instance);
30 |
31 | private:
32 | using TimePoint = std::chrono::steady_clock::time_point;
33 |
34 | // Processes all currently pending messages for registered Flutter instances.
35 | TimePoint ProcessFlutterMessages();
36 |
37 | std::set flutter_instances_;
38 | };
39 |
40 | #endif // RUNNER_RUN_LOOP_H_
41 |
--------------------------------------------------------------------------------
/example/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void CreateAndAttachConsole() {
11 | if (::AllocConsole()) {
12 | FILE *unused;
13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14 | _dup2(_fileno(stdout), 1);
15 | }
16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17 | _dup2(_fileno(stdout), 2);
18 | }
19 | std::ios::sync_with_stdio();
20 | FlutterDesktopResyncOutputStreams();
21 | }
22 | }
23 |
24 | std::vector GetCommandLineArguments() {
25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26 | int argc;
27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28 | if (argv == nullptr) {
29 | return std::vector();
30 | }
31 |
32 | std::vector command_line_arguments;
33 |
34 | // Skip the first argument as it's the binary name.
35 | for (int i = 1; i < argc; i++) {
36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37 | }
38 |
39 | ::LocalFree(argv);
40 |
41 | return command_line_arguments;
42 | }
43 |
44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45 | if (utf16_string == nullptr) {
46 | return std::string();
47 | }
48 | int target_length = ::WideCharToMultiByte(
49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50 | -1, nullptr, 0, nullptr, nullptr);
51 | if (target_length == 0) {
52 | return std::string();
53 | }
54 | std::string utf8_string;
55 | utf8_string.resize(target_length);
56 | int converted_length = ::WideCharToMultiByte(
57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
58 | -1, utf8_string.data(),
59 | target_length, nullptr, nullptr);
60 | if (converted_length == 0) {
61 | return std::string();
62 | }
63 | return utf8_string;
64 | }
65 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/example/windows/runner/win32_window.cpp:
--------------------------------------------------------------------------------
1 | #include "win32_window.h"
2 |
3 | #include
4 |
5 | #include "resource.h"
6 |
7 | namespace {
8 |
9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
10 |
11 | // The number of Win32Window objects that currently exist.
12 | static int g_active_window_count = 0;
13 |
14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
15 |
16 | // Scale helper to convert logical scaler values to physical using passed in
17 | // scale factor
18 | int Scale(int source, double scale_factor) {
19 | return static_cast(source * scale_factor);
20 | }
21 |
22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
23 | // This API is only needed for PerMonitor V1 awareness mode.
24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
25 | HMODULE user32_module = LoadLibraryA("User32.dll");
26 | if (!user32_module) {
27 | return;
28 | }
29 | auto enable_non_client_dpi_scaling =
30 | reinterpret_cast(
31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
32 | if (enable_non_client_dpi_scaling != nullptr) {
33 | enable_non_client_dpi_scaling(hwnd);
34 | FreeLibrary(user32_module);
35 | }
36 | }
37 |
38 | } // namespace
39 |
40 | // Manages the Win32Window's window class registration.
41 | class WindowClassRegistrar {
42 | public:
43 | ~WindowClassRegistrar() = default;
44 |
45 | // Returns the singleton registar instance.
46 | static WindowClassRegistrar* GetInstance() {
47 | if (!instance_) {
48 | instance_ = new WindowClassRegistrar();
49 | }
50 | return instance_;
51 | }
52 |
53 | // Returns the name of the window class, registering the class if it hasn't
54 | // previously been registered.
55 | const wchar_t* GetWindowClass();
56 |
57 | // Unregisters the window class. Should only be called if there are no
58 | // instances of the window.
59 | void UnregisterWindowClass();
60 |
61 | private:
62 | WindowClassRegistrar() = default;
63 |
64 | static WindowClassRegistrar* instance_;
65 |
66 | bool class_registered_ = false;
67 | };
68 |
69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
70 |
71 | const wchar_t* WindowClassRegistrar::GetWindowClass() {
72 | if (!class_registered_) {
73 | WNDCLASS window_class{};
74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
75 | window_class.lpszClassName = kWindowClassName;
76 | window_class.style = CS_HREDRAW | CS_VREDRAW;
77 | window_class.cbClsExtra = 0;
78 | window_class.cbWndExtra = 0;
79 | window_class.hInstance = GetModuleHandle(nullptr);
80 | window_class.hIcon =
81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
82 | window_class.hbrBackground = 0;
83 | window_class.lpszMenuName = nullptr;
84 | window_class.lpfnWndProc = Win32Window::WndProc;
85 | RegisterClass(&window_class);
86 | class_registered_ = true;
87 | }
88 | return kWindowClassName;
89 | }
90 |
91 | void WindowClassRegistrar::UnregisterWindowClass() {
92 | UnregisterClass(kWindowClassName, nullptr);
93 | class_registered_ = false;
94 | }
95 |
96 | Win32Window::Win32Window() {
97 | ++g_active_window_count;
98 | }
99 |
100 | Win32Window::~Win32Window() {
101 | --g_active_window_count;
102 | Destroy();
103 | }
104 |
105 | bool Win32Window::CreateAndShow(const std::wstring& title,
106 | const Point& origin,
107 | const Size& size) {
108 | Destroy();
109 |
110 | const wchar_t* window_class =
111 | WindowClassRegistrar::GetInstance()->GetWindowClass();
112 |
113 | const POINT target_point = {static_cast(origin.x),
114 | static_cast(origin.y)};
115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
117 | double scale_factor = dpi / 96.0;
118 |
119 | HWND window = CreateWindow(
120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor),
123 | nullptr, nullptr, GetModuleHandle(nullptr), this);
124 |
125 | if (!window) {
126 | return false;
127 | }
128 |
129 | return OnCreate();
130 | }
131 |
132 | // static
133 | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
134 | UINT const message,
135 | WPARAM const wparam,
136 | LPARAM const lparam) noexcept {
137 | if (message == WM_NCCREATE) {
138 | auto window_struct = reinterpret_cast(lparam);
139 | SetWindowLongPtr(window, GWLP_USERDATA,
140 | reinterpret_cast(window_struct->lpCreateParams));
141 |
142 | auto that = static_cast(window_struct->lpCreateParams);
143 | EnableFullDpiSupportIfAvailable(window);
144 | that->window_handle_ = window;
145 | } else if (Win32Window* that = GetThisFromHandle(window)) {
146 | return that->MessageHandler(window, message, wparam, lparam);
147 | }
148 |
149 | return DefWindowProc(window, message, wparam, lparam);
150 | }
151 |
152 | LRESULT
153 | Win32Window::MessageHandler(HWND hwnd,
154 | UINT const message,
155 | WPARAM const wparam,
156 | LPARAM const lparam) noexcept {
157 | switch (message) {
158 | case WM_DESTROY:
159 | window_handle_ = nullptr;
160 | Destroy();
161 | if (quit_on_close_) {
162 | PostQuitMessage(0);
163 | }
164 | return 0;
165 |
166 | case WM_DPICHANGED: {
167 | auto newRectSize = reinterpret_cast(lparam);
168 | LONG newWidth = newRectSize->right - newRectSize->left;
169 | LONG newHeight = newRectSize->bottom - newRectSize->top;
170 |
171 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
172 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
173 |
174 | return 0;
175 | }
176 | case WM_SIZE: {
177 | RECT rect = GetClientArea();
178 | if (child_content_ != nullptr) {
179 | // Size and position the child window.
180 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
181 | rect.bottom - rect.top, TRUE);
182 | }
183 | return 0;
184 | }
185 |
186 | case WM_ACTIVATE:
187 | if (child_content_ != nullptr) {
188 | SetFocus(child_content_);
189 | }
190 | return 0;
191 | }
192 |
193 | return DefWindowProc(window_handle_, message, wparam, lparam);
194 | }
195 |
196 | void Win32Window::Destroy() {
197 | OnDestroy();
198 |
199 | if (window_handle_) {
200 | DestroyWindow(window_handle_);
201 | window_handle_ = nullptr;
202 | }
203 | if (g_active_window_count == 0) {
204 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
205 | }
206 | }
207 |
208 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
209 | return reinterpret_cast(
210 | GetWindowLongPtr(window, GWLP_USERDATA));
211 | }
212 |
213 | void Win32Window::SetChildContent(HWND content) {
214 | child_content_ = content;
215 | SetParent(content, window_handle_);
216 | RECT frame = GetClientArea();
217 |
218 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
219 | frame.bottom - frame.top, true);
220 |
221 | SetFocus(child_content_);
222 | }
223 |
224 | RECT Win32Window::GetClientArea() {
225 | RECT frame;
226 | GetClientRect(window_handle_, &frame);
227 | return frame;
228 | }
229 |
230 | HWND Win32Window::GetHandle() {
231 | return window_handle_;
232 | }
233 |
234 | void Win32Window::SetQuitOnClose(bool quit_on_close) {
235 | quit_on_close_ = quit_on_close;
236 | }
237 |
238 | bool Win32Window::OnCreate() {
239 | // No-op; provided for subclasses.
240 | return true;
241 | }
242 |
243 | void Win32Window::OnDestroy() {
244 | // No-op; provided for subclasses.
245 | }
246 |
--------------------------------------------------------------------------------
/example/windows/runner/win32_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_WIN32_WINDOW_H_
2 | #define RUNNER_WIN32_WINDOW_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
11 | // inherited from by classes that wish to specialize with custom
12 | // rendering and input handling
13 | class Win32Window {
14 | public:
15 | struct Point {
16 | unsigned int x;
17 | unsigned int y;
18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19 | };
20 |
21 | struct Size {
22 | unsigned int width;
23 | unsigned int height;
24 | Size(unsigned int width, unsigned int height)
25 | : width(width), height(height) {}
26 | };
27 |
28 | Win32Window();
29 | virtual ~Win32Window();
30 |
31 | // Creates and shows a win32 window with |title| and position and size using
32 | // |origin| and |size|. New windows are created on the default monitor. Window
33 | // sizes are specified to the OS in physical pixels, hence to ensure a
34 | // consistent size to will treat the width height passed in to this function
35 | // as logical pixels and scale to appropriate for the default monitor. Returns
36 | // true if the window was created successfully.
37 | bool CreateAndShow(const std::wstring& title,
38 | const Point& origin,
39 | const Size& size);
40 |
41 | // Release OS resources associated with window.
42 | void Destroy();
43 |
44 | // Inserts |content| into the window tree.
45 | void SetChildContent(HWND content);
46 |
47 | // Returns the backing Window handle to enable clients to set icon and other
48 | // window properties. Returns nullptr if the window has been destroyed.
49 | HWND GetHandle();
50 |
51 | // If true, closing this window will quit the application.
52 | void SetQuitOnClose(bool quit_on_close);
53 |
54 | // Return a RECT representing the bounds of the current client area.
55 | RECT GetClientArea();
56 |
57 | protected:
58 | // Processes and route salient window messages for mouse handling,
59 | // size change and DPI. Delegates handling of these to member overloads that
60 | // inheriting classes can handle.
61 | virtual LRESULT MessageHandler(HWND window,
62 | UINT const message,
63 | WPARAM const wparam,
64 | LPARAM const lparam) noexcept;
65 |
66 | // Called when CreateAndShow is called, allowing subclass window-related
67 | // setup. Subclasses should return false if setup fails.
68 | virtual bool OnCreate();
69 |
70 | // Called when Destroy is called.
71 | virtual void OnDestroy();
72 |
73 | private:
74 | friend class WindowClassRegistrar;
75 |
76 | // OS callback called by message pump. Handles the WM_NCCREATE message which
77 | // is passed when the non-client area is being created and enables automatic
78 | // non-client DPI scaling so that the non-client area automatically
79 | // responsponds to changes in DPI. All other messages are handled by
80 | // MessageHandler.
81 | static LRESULT CALLBACK WndProc(HWND const window,
82 | UINT const message,
83 | WPARAM const wparam,
84 | LPARAM const lparam) noexcept;
85 |
86 | // Retrieves a class instance pointer for |window|
87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept;
88 |
89 | bool quit_on_close_ = false;
90 |
91 | // window handle for top level window.
92 | HWND window_handle_ = nullptr;
93 |
94 | // window handle for hosted content.
95 | HWND child_content_ = nullptr;
96 | };
97 |
98 | #endif // RUNNER_WIN32_WINDOW_H_
99 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/Generated.xcconfig
37 | /Flutter/flutter_export_environment.sh
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuelongqy/flutter_jscore/dd8bf1153c7a8bfc78adfd24accb129740b8aa29/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/FlutterJscorePlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface FlutterJscorePlugin : NSObject
4 | @end
5 |
--------------------------------------------------------------------------------
/ios/Classes/FlutterJscorePlugin.m:
--------------------------------------------------------------------------------
1 | #import "FlutterJscorePlugin.h"
2 | #if __has_include()
3 | #import
4 | #else
5 | // Support project import fallback if the generated compatibility header
6 | // is not copied when this plugin is created as a library.
7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
8 | #import "flutter_jscore-Swift.h"
9 | #endif
10 |
11 | @implementation FlutterJscorePlugin
12 | + (void)registerWithRegistrar:(NSObject*)registrar {
13 | [SwiftFlutterJscorePlugin registerWithRegistrar:registrar];
14 | }
15 | @end
16 |
--------------------------------------------------------------------------------
/ios/Classes/SwiftFlutterJscorePlugin.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 |
4 | public class SwiftFlutterJscorePlugin: NSObject, FlutterPlugin {
5 | public static func register(with registrar: FlutterPluginRegistrar) {
6 | let channel = FlutterMethodChannel(name: "flutter_jscore", binaryMessenger: registrar.messenger())
7 | let instance = SwiftFlutterJscorePlugin()
8 | registrar.addMethodCallDelegate(instance, channel: channel)
9 | }
10 |
11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
12 | result("iOS " + UIDevice.current.systemVersion)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ios/flutter_jscore.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3 | # Run `pod lib lint flutter_jscore.podspec' to validate before publishing.
4 | #
5 | Pod::Spec.new do |s|
6 | s.name = 'flutter_jscore'
7 | s.version = '0.0.1'
8 | s.summary = 'JavaScriptCore for Flutter.'
9 | s.description = <<-DESC
10 | JavaScriptCore for Flutter.
11 | DESC
12 | s.homepage = 'http://example.com'
13 | s.license = { :file => '../LICENSE' }
14 | s.author = { 'Your Company' => 'email@example.com' }
15 | s.source = { :path => '.' }
16 | s.source_files = 'Classes/**/*'
17 | s.dependency 'Flutter'
18 | s.platform = :ios, '8.0'
19 | s.frameworks = 'JavaScriptCore'
20 |
21 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
23 | s.swift_version = '5.0'
24 | end
25 |
--------------------------------------------------------------------------------
/lib/binding/js_base.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'jsc_ffi.dart';
4 |
5 | /// typedef JSTypedArrayBytesDeallocator A function used to deallocate bytes passed to a Typed Array constructor. The function should take two arguments. The first is a pointer to the bytes that were originally passed to the Typed Array constructor. The second is a pointer to additional information desired at the time the bytes are to be freed.
6 | /// typedef void (*JSTypedArrayBytesDeallocator)(void* bytes, void* deallocatorContext);
7 | typedef JSTypedArrayBytesDeallocator = Void Function(
8 | Pointer bytes, Pointer deallocatorContext);
9 | typedef JSTypedArrayBytesDeallocatorDart = void Function(
10 | Pointer bytes, Pointer deallocatorContext);
11 |
12 | /// Evaluates a string of JavaScript.
13 | /// [ctx] (JSContextRef) The execution context to use.
14 | /// [script] (JSStringRef) A JSString containing the script to evaluate.
15 | /// [thisObject] (JSObjectRef) The object to use as "this," or NULL to use the global object as "this."
16 | /// [sourceURL] (JSStringRef) A JSString containing a URL for the script's source file. This is used by debuggers and when reporting exceptions. Pass NULL if you do not care to include source file information.
17 | /// [startingLineNumber] (int) An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
18 | /// [exception] (JSValueRef*) A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
19 | /// [@result] (JSValueRef) The JSValue that results from evaluating script, or NULL if an exception is thrown.
20 | final Pointer Function(Pointer ctx, Pointer script, Pointer thisObject,
21 | Pointer sourceURL, int startingLineNumber, Pointer exception)
22 | jSEvaluateScript = JscFfi.lib
23 | .lookup<
24 | NativeFunction<
25 | Pointer Function(Pointer, Pointer, Pointer, Pointer, Int32,
26 | Pointer)>>('JSEvaluateScript')
27 | .asFunction();
28 |
29 | /// Checks for syntax errors in a string of JavaScript.
30 | /// [ctx] (JSContextRef) The execution context to use.
31 | /// [script] (JSStringRef) A JSString containing the script to check for syntax errors.
32 | /// [sourceURL] (JSStringRef) A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions.
33 | /// [startingLineNumber] (int) An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
34 | /// [exception] (JSValueRef*) A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception.
35 | /// [@result] (bool) true if the script is syntactically correct, otherwise false.
36 | final Pointer Function(Pointer ctx, Pointer script, Pointer sourceURL,
37 | int startingLineNumber, Pointer exception)
38 | jSCheckScriptSyntax = JscFfi.lib
39 | .lookup<
40 | NativeFunction<
41 | Pointer Function(Pointer, Pointer, Pointer, Int32,
42 | Pointer)>>('JSCheckScriptSyntax')
43 | .asFunction();
44 |
45 | /// Performs a JavaScript garbage collection.
46 | /// JavaScript values that are on the machine stack, in a register,
47 | /// protected by JSValueProtect, set as the global object of an execution context,
48 | /// or reachable from any such value will not be collected.
49 | ///
50 | /// During JavaScript execution, you are not required to call this function; the
51 | /// JavaScript engine will garbage collect as needed. JavaScript values created
52 | /// within a context group are automatically destroyed when the last reference
53 | /// to the context group is released.
54 | /// [ctx] (JSContextRef) The execution context to use.
55 | final void Function(Pointer ctx) jSGarbageCollect = JscFfi.lib
56 | .lookup>('JSGarbageCollect')
57 | .asFunction();
58 |
--------------------------------------------------------------------------------
/lib/binding/js_context_ref.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'jsc_ffi.dart';
4 |
5 | /// Creates a JavaScript context group.
6 | /// A JSContextGroup associates JavaScript contexts with one another.
7 | /// Contexts in the same group may share and exchange JavaScript objects. Sharing and/or exchanging
8 | /// JavaScript objects between contexts in different groups will produce undefined behavior.
9 | /// When objects from the same context group are used in multiple threads, explicit
10 | /// synchronization is required.
11 | ///
12 | /// A JSContextGroup may need to run deferred tasks on a run loop, such as garbage collection
13 | /// or resolving WebAssembly compilations. By default, calling JSContextGroupCreate will use
14 | /// the run loop of the thread it was called on. Currently, there is no API to change a
15 | /// JSContextGroup's run loop once it has been created.
16 | /// [@result] (JSContextGroupRef) The created JSContextGroup.
17 | final Pointer Function() jSContextGroupCreate = JscFfi.lib
18 | .lookup>('JSContextGroupCreate')
19 | .asFunction();
20 |
21 | /// Retains a JavaScript context group.
22 | /// [group] (JSContextGroupRef) The JSContextGroup to retain.
23 | /// [@result] (JSContextGroupRef) A JSContextGroup that is the same as group.
24 | final Pointer Function(Pointer group) jSContextGroupRetain = JscFfi.lib
25 | .lookup>('JSContextGroupRetain')
26 | .asFunction();
27 |
28 | /// Releases a JavaScript context group.
29 | /// [group] (JSContextGroupRef) The JSContextGroup to release.
30 | final void Function(Pointer group) jSContextGroupRelease = JscFfi.lib
31 | .lookup>('JSContextGroupRelease')
32 | .asFunction();
33 |
34 | /// Creates a global JavaScript execution context.
35 | /// JSGlobalContextCreate allocates a global object and populates it with all the
36 | /// built-in JavaScript objects, such as Object, Function, String, and Array.
37 | ///
38 | /// In WebKit version 4.0 and later, the context is created in a unique context group.
39 | /// Therefore, scripts may execute in it concurrently with scripts executing in other contexts.
40 | /// However, you may not use values created in the context in other contexts.
41 | /// [globalObjectClass] (JSClassRef) The class to use when creating the global object. Pass NULL to use the default object class.
42 | /// [@result] (JSGlobalContextRef) A JSGlobalContext with a global object of class globalObjectClass.
43 | final Pointer Function(Pointer globalObjectClass) jSGlobalContextCreate = JscFfi
44 | .lib
45 | .lookup>('JSGlobalContextCreate')
46 | .asFunction();
47 |
48 | /// Creates a global JavaScript execution context in the context group provided.
49 | /// JSGlobalContextCreateInGroup allocates a global object and populates it with
50 | /// all the built-in JavaScript objects, such as Object, Function, String, and Array.
51 | /// [group] (JSContextGroupRef) The context group to use. The created global context retains the group. Pass NULL to create a unique group for the context.
52 | /// [globalObjectClass] (JSClassRef) The class to use when creating the global object. Pass NULL to use the default object class.
53 | /// [@result] (JSGlobalContextRef) A JSGlobalContext with a global object of class globalObjectClass and a context group equal to group.
54 | final Pointer Function(Pointer group, Pointer globalObjectClass)
55 | jSGlobalContextCreateInGroup = JscFfi.lib
56 | .lookup>(
57 | 'JSGlobalContextCreateInGroup')
58 | .asFunction();
59 |
60 | /// Retains a global JavaScript execution context.
61 | /// [ctx] (JSGlobalContextRef) The JSGlobalContext to retain.
62 | /// [@result] (JSGlobalContextRef) A JSGlobalContext that is the same as ctx.
63 | final Pointer Function(Pointer ctx) jSGlobalContextRetain = JscFfi.lib
64 | .lookup>('JSGlobalContextRetain')
65 | .asFunction();
66 |
67 | /// Releases a global JavaScript execution context.
68 | /// [ctx] (JSGlobalContextRef) The JSGlobalContext to release.
69 | final void Function(Pointer ctx) jSGlobalContextRelease = JscFfi.lib
70 | .lookup>('JSGlobalContextRelease')
71 | .asFunction();
72 |
73 | /// Gets the global object of a JavaScript execution context.
74 | /// [ctx] (JSContextRef) The JSContext whose global object you want to get.
75 | /// [@result] (JSObjectRef) ctx's global object.
76 | final Pointer Function(Pointer ctx) jSContextGetGlobalObject = JscFfi.lib
77 | .lookup>(
78 | 'JSContextGetGlobalObject')
79 | .asFunction();
80 |
81 | /// Gets the context group to which a JavaScript execution context belongs.
82 | /// [ctx] (JSContextRef) The JSContext whose group you want to get.
83 | /// [@result] (JSContextGroupRef) ctx's group.
84 | final Pointer Function(Pointer ctx) jSContextGetGroup = JscFfi.lib
85 | .lookup>('JSContextGetGroup')
86 | .asFunction();
87 |
88 | /// Gets the global context of a JavaScript execution context.
89 | /// [ctx] (JSContextRef) The JSContext whose global context you want to get.
90 | /// [@result] (JSGlobalContextRef) ctx's global context.
91 | final Pointer Function(Pointer ctx) jSContextGetGlobalContext = JscFfi.lib
92 | .lookup>(
93 | 'JSContextGetGlobalContext')
94 | .asFunction();
95 |
96 | /// Gets a copy of the name of a context.
97 | /// A JSGlobalContext's name is exposed for remote debugging to make it
98 | /// easier to identify the context you would like to attach to.
99 | /// [ctx] (JSGlobalContextRef) The JSGlobalContext whose name you want to get.
100 | /// [@result] (JSStringRef) The name for ctx.
101 | final Pointer Function(Pointer ctx) jSGlobalContextCopyName = JscFfi.lib
102 | .lookup>(
103 | 'JSGlobalContextCopyName')
104 | .asFunction();
105 |
106 | /// Sets the remote debugging name for a context.
107 | /// [ctx] (JSGlobalContextRef) The JSGlobalContext that you want to name.
108 | /// [name] (JSStringRef) The remote debugging name to set on ctx.
109 | final void Function(Pointer ctx, Pointer name) jSGlobalContextSetName = JscFfi
110 | .lib
111 | .lookup>(
112 | 'JSGlobalContextSetName')
113 | .asFunction();
114 |
--------------------------------------------------------------------------------
/lib/binding/js_string_ref.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'package:ffi/ffi.dart';
4 |
5 | import 'jsc_ffi.dart';
6 |
7 | /// Creates a JavaScript string from a buffer of Unicode characters.
8 | /// [chars] (JSChar*) The buffer of Unicode characters to copy into the new JSString.
9 | /// [numChars] (size_t) The number of characters to copy from the buffer pointed to by chars.
10 | /// [@result] (JSStringRef) A JSString containing chars. Ownership follows the Create Rule.
11 | final Pointer Function(Pointer chars, Pointer numChars)
12 | jSStringCreateWithCharacters = JscFfi.lib
13 | .lookup, Pointer)>>(
14 | 'JSStringCreateWithCharacters')
15 | .asFunction();
16 |
17 | /// Creates a JavaScript string from a null-terminated UTF8 string.
18 | /// [string] (char*) The null-terminated UTF8 string to copy into the new JSString.
19 | /// [@result] (JSStringRef) A JSString containing string. Ownership follows the Create Rule.
20 | final Pointer Function(Pointer string) jSStringCreateWithUTF8CString =
21 | JscFfi.lib
22 | .lookup)>>(
23 | 'JSStringCreateWithUTF8CString')
24 | .asFunction();
25 |
26 | /// Retains a JavaScript string.
27 | /// [string] (JSStringRef) The JSString to retain.
28 | /// [@result] (JSStringRef) A JSString that is the same as string.
29 | final Pointer Function(Pointer string) jSStringRetain = JscFfi.lib
30 | .lookup>('JSStringRetain')
31 | .asFunction();
32 |
33 | /// Releases a JavaScript string.
34 | /// [string] (JSStringRef) The JSString to release.
35 | final void Function(Pointer string) jSStringRelease = JscFfi.lib
36 | .lookup>('JSStringRelease')
37 | .asFunction();
38 |
39 | /// Returns the number of Unicode characters in a JavaScript string.
40 | /// [string] (JSStringRef) The JSString whose length (in Unicode characters) you want to know.
41 | /// [@result] (size_t) The number of Unicode characters stored in string.
42 | final int Function(Pointer string) jSStringGetLength = JscFfi.lib
43 | .lookup>('JSStringGetLength')
44 | .asFunction();
45 |
46 | /// Returns a pointer to the Unicode character buffer that
47 | /// serves as the backing store for a JavaScript string.
48 | /// [string] (JSStringRef) The JSString whose backing store you want to access.
49 | /// [@result] (const JSChar*) A pointer to the Unicode character buffer that serves as string's backing store, which will be deallocated when string is deallocated.
50 | final Pointer Function(Pointer string) jSStringGetCharactersPtr = JscFfi
51 | .lib
52 | .lookup Function(Pointer)>>(
53 | 'JSStringGetCharactersPtr')
54 | .asFunction();
55 |
56 | /// Returns the maximum number of bytes a JavaScript string will
57 | /// take up if converted into a null-terminated UTF8 string.
58 | /// [string] (JSStringRef) The JSString whose maximum converted size (in bytes) you want to know.
59 | /// [@result] (size_t) The maximum number of bytes that could be required to convert string into a null-terminated UTF8 string. The number of bytes that the conversion actually ends up requiring could be less than this, but never more.
60 | final int Function(Pointer string) jSStringGetMaximumUTF8CStringSize = JscFfi
61 | .lib
62 | .lookup>(
63 | 'JSStringGetMaximumUTF8CStringSize')
64 | .asFunction();
65 |
66 | /// Converts a JavaScript string into a null-terminated UTF8 string,
67 | /// and copies the result into an external byte buffer.
68 | /// [string] (JSStringRef) The source JSString.
69 | /// [buffer] (char*) The destination byte buffer into which to copy a null-terminated UTF8 representation of string. On return, buffer contains a UTF8 string representation of string. If bufferSize is too small, buffer will contain only partial results. If buffer is not at least bufferSize bytes in size, behavior is undefined.
70 | /// [bufferSize] (size_t) The size of the external buffer in bytes.
71 | /// [@result] (size_t) The number of bytes written into buffer (including the null-terminator byte).
72 | final int Function(Pointer string, Pointer buffer, int bufferSize)
73 | jSStringGetUTF8CString = JscFfi.lib
74 | .lookup>(
75 | 'JSStringGetUTF8CString')
76 | .asFunction();
77 |
78 | /// Tests whether two JavaScript strings match.
79 | /// [a] (JSStringRef) The first JSString to test.
80 | /// [b] (JSStringRef) The second JSString to test.
81 | /// [@result] (bool) true if the two strings match, otherwise false.
82 | final int Function(Pointer a, Pointer b) jSStringIsEqual = JscFfi.lib
83 | .lookup>('JSStringIsEqual')
84 | .asFunction();
85 |
86 | /// Tests whether a JavaScript string matches a null-terminated UTF8 string.
87 | /// [a] (JSStringRef) The JSString to test.
88 | /// [b] (char*) The null-terminated UTF8 string to test.
89 | /// [@result] (bool) true if the two strings match, otherwise false.
90 | final Pointer Function(Pointer a, Pointer b) jSStringIsEqualToUTF8CString =
91 | JscFfi.lib
92 | .lookup>(
93 | 'JSStringIsEqualToUTF8CString')
94 | .asFunction();
95 |
--------------------------------------------------------------------------------
/lib/binding/jsc_ffi.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 | import 'dart:io';
3 |
4 | class JscFfi {
5 | /// You can replace it with the version you want
6 | static DynamicLibrary lib = Platform.isIOS || Platform.isMacOS
7 | ? DynamicLibrary.open('JavaScriptCore.framework/JavaScriptCore')
8 | : Platform.isWindows
9 | ? DynamicLibrary.open('JavaScriptCore.dll')
10 | : Platform.isLinux
11 | ? DynamicLibrary.open('libjavascriptcoregtk-4.0.so.18')
12 | : DynamicLibrary.open('libjsc.so');
13 | }
14 |
--------------------------------------------------------------------------------
/lib/flutter_jscore.dart:
--------------------------------------------------------------------------------
1 | export 'jscore/js_class.dart';
2 | export 'jscore/js_context_group.dart';
3 | export 'jscore/js_context.dart';
4 | export 'jscore/js_object.dart';
5 | export 'jscore/js_property_name_accumulator.dart';
6 | export 'jscore/js_property_name_array.dart';
7 | export 'jscore/js_string.dart';
8 | export 'jscore/js_value.dart';
9 |
10 | //import 'dart:async';
11 | //
12 | //import 'package:flutter/services.dart';
13 | //
14 | //class FlutterJscore {
15 | // static const MethodChannel _channel = const MethodChannel('flutter_jscore');
16 | //
17 | // static Future get platformVersion async {
18 | // final String version = await _channel.invokeMethod('getPlatformVersion');
19 | // return version;
20 | // }
21 | //}
22 |
--------------------------------------------------------------------------------
/lib/jscore/js_class.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'package:flutter_jscore/binding/js_object_ref.dart' as JSObjectRef;
4 |
5 | import 'js_object.dart';
6 |
7 | /// A JavaScript class. Used with JSObjectMake to construct objects with custom behavior.
8 | class JSClass {
9 | /// C pointer
10 | Pointer pointer;
11 |
12 | JSClass(this.pointer);
13 |
14 | /// Creates a JavaScript class suitable for use with JSObjectMake.
15 | /// [definition] (JSClassDefinition*) A JSClassDefinition that defines the class.
16 | JSClass.create(JSClassDefinition definition)
17 | : this.pointer = JSObjectRef.jSClassCreate(definition.create());
18 |
19 | /// Retains a JavaScript class.
20 | void retain() {
21 | pointer = JSObjectRef.jSClassRetain(pointer);
22 | }
23 |
24 | /// Releases a JavaScript class.
25 | void release() {
26 | JSObjectRef.jSClassRelease(pointer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/jscore/js_context.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import '../binding/js_base.dart' as JSBase;
4 | import '../binding/js_context_ref.dart' as JSContextRef;
5 | import 'js_class.dart';
6 | import 'js_context_group.dart';
7 | import 'js_object.dart';
8 | import 'js_string.dart';
9 | import 'js_value.dart';
10 |
11 | /// A JavaScript execution context. Holds the global object and other execution state.
12 | class JSContext {
13 | /// C pointer
14 | Pointer _pointer;
15 | Pointer get pointer => _pointer;
16 |
17 | /// Exception (JSValueRef*) A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
18 | JSValuePointer exception = JSValuePointer();
19 |
20 | JSContext(this._pointer);
21 |
22 | /// Creates a global JavaScript execution context.
23 | /// JSGlobalContextCreate allocates a global object and populates it with all the
24 | /// built-in JavaScript objects, such as Object, Function, String, and Array.
25 | ///
26 | /// In WebKit version 4.0 and later, the context is created in a unique context group.
27 | /// Therefore, scripts may execute in it concurrently with scripts executing in other contexts.
28 | /// However, you may not use values created in the context in other contexts.
29 | /// [globalObjectClass] (JSClass) The class to use when creating the global object. Pass NULL to use the default object class.
30 | /// [@result] (JSGlobalContext) A JSGlobalContext with a global object of class globalObjectClass.
31 | JSContext.create({
32 | JSClass? globalObjectClass,
33 | }) : this._pointer = JSContextRef.jSGlobalContextCreate(
34 | globalObjectClass == null ? nullptr : globalObjectClass.pointer);
35 |
36 | /// Creates a global JavaScript execution context in the context group provided.
37 | /// JSGlobalContextCreateInGroup allocates a global object and populates it with
38 | /// all the built-in JavaScript objects, such as Object, Function, String, and Array.
39 | /// [group] (JSContextGroup) The context group to use. The created global context retains the group. Pass NULL to create a unique group for the context.
40 | /// [globalObjectClass] (JSClass) The class to use when creating the global object. Pass NULL to use the default object class.
41 | /// [@result] (JSGlobalContext) A JSGlobalContext with a global object of class globalObjectClass and a context group equal to group.
42 | JSContext.createInGroup({
43 | JSContextGroup? group,
44 | JSClass? globalObjectClass,
45 | }) : this._pointer = JSContextRef.jSGlobalContextCreateInGroup(
46 | group == null ? JSContextRef.jSContextGroupCreate() : group.pointer,
47 | globalObjectClass == null ? nullptr : globalObjectClass.pointer);
48 |
49 | /// Retains a global JavaScript execution context.
50 | /// [@result] (JSGlobalContext) A JSGlobalContext that is the same as ctx.
51 | void retain() {
52 | _pointer = JSContextRef.jSGlobalContextRetain(pointer);
53 | }
54 |
55 | /// Releases a global JavaScript execution context.
56 | /// [ctx] (JSGlobalContext) The JSGlobalContext to release.
57 | void release() {
58 | return JSContextRef.jSGlobalContextRelease(pointer);
59 | }
60 |
61 | /// Gets the global object of a JavaScript execution context.
62 | /// [@result] (JSObject) ctx's global object.
63 | JSObject get globalObject {
64 | return JSObject(this, JSContextRef.jSContextGetGlobalObject(pointer));
65 | }
66 |
67 | /// Gets the context group to which a JavaScript execution context belongs.
68 | /// [@result] (JSContextGroup) ctx's group.
69 | JSContextGroup get group {
70 | return JSContextGroup(JSContextRef.jSContextGetGroup(pointer));
71 | }
72 |
73 | /// Gets the global context of a JavaScript execution context.
74 | /// [@result] (JSGlobalContext) ctx's global context.
75 | /*JSGlobalContext get globalContext {
76 | return JSGlobalContext(JSContextRef.jSContextGetGlobalContext(pointer));
77 | }*/
78 |
79 | /// Gets a copy of the name of a context.
80 | /// A JSGlobalContext's name is exposed for remote debugging to make it
81 | /// easier to identify the context you would like to attach to.
82 | /// [@result] (JSString) The name for ctx.
83 | JSString copyName() {
84 | return JSString(JSContextRef.jSGlobalContextCopyName(pointer));
85 | }
86 |
87 | /// Sets the remote debugging name for a context.
88 | /// [name] (JSString) The remote debugging name to set on ctx.
89 | void setName(JSString name) {
90 | return JSContextRef.jSGlobalContextSetName(pointer, name.pointer);
91 | }
92 |
93 | /// Evaluates a string of JavaScript.
94 | /// [script] (String) A JSString containing the script to evaluate.
95 | /// [thisObject] (JSObject) The object to use as "this," or NULL to use the global object as "this."
96 | /// [sourceURL] (String) A JSString containing a URL for the script's source file. This is used by debuggers and when reporting exceptions. Pass NULL if you do not care to include source file information.
97 | /// [startingLineNumber] (int) An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1.
98 | /// [@result] (JSValueRef) The JSValue that results from evaluating script, or NULL if an exception is thrown.
99 | JSValue evaluate(
100 | String script, {
101 | JSObject? thisObject,
102 | String? sourceURL,
103 | int startingLineNumber = 1,
104 | }) {
105 | return JSValue(
106 | this,
107 | JSBase.jSEvaluateScript(
108 | pointer,
109 | JSString.fromString(script).pointer,
110 | thisObject == null ? nullptr : thisObject.pointer,
111 | sourceURL == null ? nullptr : JSString.fromString(sourceURL).pointer,
112 | startingLineNumber,
113 | exception.pointer,
114 | ));
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/jscore/js_context_group.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 | import '../binding/js_context_ref.dart' as JSContextRef;
3 |
4 | /// JSContextGroupRef A group that associates JavaScript contexts with one another. Contexts in the same group may share and exchange JavaScript objects.
5 | class JSContextGroup {
6 | /// C pointer
7 | final Pointer pointer;
8 |
9 | JSContextGroup(this.pointer);
10 |
11 | /// Creates a JavaScript context group.
12 | /// A JSContextGroup associates JavaScript contexts with one another.
13 | /// Contexts in the same group may share and exchange JavaScript objects. Sharing and/or exchanging
14 | /// JavaScript objects between contexts in different groups will produce undefined behavior.
15 | /// When objects from the same context group are used in multiple threads, explicit
16 | /// synchronization is required.
17 | ///
18 | /// A JSContextGroup may need to run deferred tasks on a run loop, such as garbage collection
19 | /// or resolving WebAssembly compilations. By default, calling JSContextGroupCreate will use
20 | /// the run loop of the thread it was called on. Currently, there is no API to change a
21 | /// JSContextGroup's run loop once it has been created.
22 | JSContextGroup.create() : this.pointer = JSContextRef.jSContextGroupCreate();
23 |
24 | /// Retains a JavaScript context group.
25 | /// [@result] (JSContextGroupRef) A JSContextGroup that is the same as group.
26 | JSContextGroup retain() {
27 | return JSContextGroup(JSContextRef.jSContextGroupRetain(pointer));
28 | }
29 |
30 | /// Releases a JavaScript context group.
31 | void release() {
32 | return JSContextRef.jSContextGroupRelease(pointer);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/jscore/js_property_name_accumulator.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | /// An ordered set used to collect the names of a JavaScript object's properties.
4 | class JSPropertyNameAccumulator {
5 | /// C pointer
6 | final Pointer pointer;
7 |
8 | JSPropertyNameAccumulator(this.pointer);
9 | }
10 |
--------------------------------------------------------------------------------
/lib/jscore/js_property_name_array.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 |
3 | import 'package:flutter_jscore/binding/js_object_ref.dart' as JSObjectRef;
4 |
5 | import 'js_string.dart';
6 |
7 | /// An array of JavaScript property names.
8 | class JSPropertyNameArray {
9 | /// C pointer
10 | Pointer pointer;
11 |
12 | JSPropertyNameArray(this.pointer);
13 |
14 | /// Retains a JavaScript property name array.
15 | void retain() {
16 | pointer = JSObjectRef.jSPropertyNameArrayRetain(pointer);
17 | }
18 |
19 | /// Releases a JavaScript property name array.
20 | void release() {
21 | JSObjectRef.jSPropertyNameArrayRelease(pointer);
22 | }
23 |
24 | /// Gets a count of the number of items in a JavaScript property name array.
25 | int get count {
26 | return JSObjectRef.jSPropertyNameArrayGetCount(pointer);
27 | }
28 |
29 | /// Gets a property name at a given index in a JavaScript property name array.
30 | /// [index] (size_t) The index of the property name to retrieve.
31 | String propertyNameArrayGetNameAtIndex(int index) {
32 | return JSString(
33 | JSObjectRef.jSPropertyNameArrayGetNameAtIndex(pointer, index))
34 | .string!;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/jscore/js_string.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ffi';
2 | import 'dart:typed_data';
3 |
4 | import 'package:ffi/ffi.dart';
5 |
6 | import '../binding/js_string_ref.dart' as JSStringRef;
7 |
8 | /// A UTF16 character buffer. The fundamental string representation in JavaScript.
9 | class JSString {
10 | /// C pointer
11 | late Pointer _pointer;
12 | get pointer => _pointer;
13 |
14 | JSString(this._pointer);
15 |
16 | /// Creates a JavaScript string from dart String.
17 | /// [string] The dart String.
18 | JSString.fromString(String? string) {
19 | if (string == null) {
20 | _pointer = nullptr;
21 | } else {
22 | var cString = string.toNativeUtf8();
23 | _pointer = JSStringRef.jSStringCreateWithUTF8CString(cString);
24 | malloc.free(cString);
25 | }
26 | }
27 |
28 | /// Retains a JavaScript string.
29 | /// [@result] (JSStringRef) A JSString that is the same as string.
30 | void retain() {
31 | _pointer = JSStringRef.jSStringRetain(_pointer);
32 | }
33 |
34 | /// Releases a JavaScript string.
35 | void release() {
36 | if (_pointer != nullptr) {
37 | JSStringRef.jSStringRelease(_pointer);
38 | }
39 | }
40 |
41 | /// Returns the number of Unicode characters in a JavaScript string.
42 | int get length {
43 | return JSStringRef.jSStringGetLength(_pointer);
44 | }
45 |
46 | /// Returns dart String
47 | String? get string {
48 | if (_pointer == nullptr) return null;
49 | var cString = JSStringRef.jSStringGetCharactersPtr(_pointer);
50 | if (cString == nullptr) {
51 | return null;
52 | }
53 | int cStringLength = JSStringRef.jSStringGetLength(_pointer);
54 | return String.fromCharCodes(Uint16List.view(
55 | cString.cast().asTypedList(cStringLength).buffer,
56 | 0,
57 | cStringLength));
58 | }
59 |
60 | @override
61 | bool operator ==(Object other) =>
62 | identical(this, other) ||
63 | other is JSString &&
64 | runtimeType == other.runtimeType &&
65 | JSStringRef.jSStringIsEqual(_pointer, other.pointer) == 1 ||
66 | other is String && string == other;
67 |
68 | @override
69 | int get hashCode => _pointer.hashCode;
70 | }
71 |
72 | /// JSStringRef pointer
73 | class JSStringPointer {
74 | /// C pointer
75 | final Pointer pointer;
76 |
77 | /// Pointer array count
78 | final int count;
79 |
80 | JSStringPointer([Pointer? value])
81 | : this.count = 1,
82 | this.pointer = malloc.call(1) {
83 | pointer.value = value ?? nullptr;
84 | }
85 |
86 | /// JSStringRef array
87 | JSStringPointer.array(List array)
88 | : this.count = array.length,
89 | this.pointer = malloc.call(array.length) {
90 | for (int i = 0; i < array.length; i++) {
91 | this.pointer[i] = JSString.fromString(array[i]).pointer;
92 | }
93 | }
94 |
95 | /// Get JSValue
96 | /// [index] Array index
97 | JSString getValue([int index = 0]) {
98 | return JSString(pointer[index]);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lib/jscore_bindings.dart:
--------------------------------------------------------------------------------
1 | export 'binding/js_base.dart';
2 | export 'binding/js_context_ref.dart';
3 | export 'binding/js_string_ref.dart';
4 | export 'binding/js_value_ref.dart';
5 | export 'binding/js_object_ref.dart';
6 | export 'binding/js_typed_array.dart';
7 | export 'binding/jsc_ffi.dart';
8 |
--------------------------------------------------------------------------------
/linux/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 | set(PROJECT_NAME "flutter_jscore")
3 | project(${PROJECT_NAME} LANGUAGES CXX)
4 |
5 | # This value is used when generating builds using this plugin, so it must
6 | # not be changed
7 | set(PLUGIN_NAME "flutter_jscore_plugin")
8 |
9 | add_library(${PLUGIN_NAME} SHARED
10 | "flutter_jscore_plugin.cc"
11 | )
12 | apply_standard_settings(${PLUGIN_NAME})
13 | set_target_properties(${PLUGIN_NAME} PROPERTIES
14 | CXX_VISIBILITY_PRESET hidden)
15 | target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
16 | target_include_directories(${PLUGIN_NAME} INTERFACE
17 | "${CMAKE_CURRENT_SOURCE_DIR}/include")
18 | target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
19 | target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
20 |
21 | # List of absolute paths to libraries that should be bundled with the plugin
22 | set(flutter_jscore_bundled_libraries
23 | ""
24 | PARENT_SCOPE
25 | )
26 |
--------------------------------------------------------------------------------
/linux/flutter_jscore_plugin.cc:
--------------------------------------------------------------------------------
1 | #include "include/flutter_jscore/flutter_jscore_plugin.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #define FLUTTER_JSCORE_PLUGIN(obj) \
10 | (G_TYPE_CHECK_INSTANCE_CAST((obj), flutter_jscore_plugin_get_type(), \
11 | FlutterJscorePlugin))
12 |
13 | struct _FlutterJscorePlugin {
14 | GObject parent_instance;
15 | };
16 |
17 | G_DEFINE_TYPE(FlutterJscorePlugin, flutter_jscore_plugin, g_object_get_type())
18 |
19 | // Called when a method call is received from Flutter.
20 | static void flutter_jscore_plugin_handle_method_call(
21 | FlutterJscorePlugin* self,
22 | FlMethodCall* method_call) {
23 | g_autoptr(FlMethodResponse) response = nullptr;
24 |
25 | const gchar* method = fl_method_call_get_name(method_call);
26 |
27 | if (strcmp(method, "getPlatformVersion") == 0) {
28 | struct utsname uname_data = {};
29 | uname(&uname_data);
30 | g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version);
31 | g_autoptr(FlValue) result = fl_value_new_string(version);
32 | response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
33 | } else {
34 | response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
35 | }
36 |
37 | fl_method_call_respond(method_call, response, nullptr);
38 | }
39 |
40 | static void flutter_jscore_plugin_dispose(GObject* object) {
41 | G_OBJECT_CLASS(flutter_jscore_plugin_parent_class)->dispose(object);
42 | }
43 |
44 | static void flutter_jscore_plugin_class_init(FlutterJscorePluginClass* klass) {
45 | G_OBJECT_CLASS(klass)->dispose = flutter_jscore_plugin_dispose;
46 | }
47 |
48 | static void flutter_jscore_plugin_init(FlutterJscorePlugin* self) {}
49 |
50 | static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call,
51 | gpointer user_data) {
52 | FlutterJscorePlugin* plugin = FLUTTER_JSCORE_PLUGIN(user_data);
53 | flutter_jscore_plugin_handle_method_call(plugin, method_call);
54 | }
55 |
56 | void flutter_jscore_plugin_register_with_registrar(FlPluginRegistrar* registrar) {
57 | FlutterJscorePlugin* plugin = FLUTTER_JSCORE_PLUGIN(
58 | g_object_new(flutter_jscore_plugin_get_type(), nullptr));
59 |
60 | g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
61 | g_autoptr(FlMethodChannel) channel =
62 | fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar),
63 | "flutter_jscore",
64 | FL_METHOD_CODEC(codec));
65 | fl_method_channel_set_method_call_handler(channel, method_call_cb,
66 | g_object_ref(plugin),
67 | g_object_unref);
68 |
69 | g_object_unref(plugin);
70 | }
71 |
--------------------------------------------------------------------------------
/linux/include/flutter_jscore/flutter_jscore_plugin.h:
--------------------------------------------------------------------------------
1 | #ifndef FLUTTER_PLUGIN_FLUTTER_JSCORE_PLUGIN_H_
2 | #define FLUTTER_PLUGIN_FLUTTER_JSCORE_PLUGIN_H_
3 |
4 | #include
5 |
6 | G_BEGIN_DECLS
7 |
8 | #ifdef FLUTTER_PLUGIN_IMPL
9 | #define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
10 | #else
11 | #define FLUTTER_PLUGIN_EXPORT
12 | #endif
13 |
14 | typedef struct _FlutterJscorePlugin FlutterJscorePlugin;
15 | typedef struct {
16 | GObjectClass parent_class;
17 | } FlutterJscorePluginClass;
18 |
19 | FLUTTER_PLUGIN_EXPORT GType flutter_jscore_plugin_get_type();
20 |
21 | FLUTTER_PLUGIN_EXPORT void flutter_jscore_plugin_register_with_registrar(
22 | FlPluginRegistrar* registrar);
23 |
24 | G_END_DECLS
25 |
26 | #endif // FLUTTER_PLUGIN_FLUTTER_JSCORE_PLUGIN_H_
27 |
--------------------------------------------------------------------------------
/macos/Classes/FlutterJscorePlugin.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | public class FlutterJscorePlugin: NSObject, FlutterPlugin {
5 | public static func register(with registrar: FlutterPluginRegistrar) {
6 | let channel = FlutterMethodChannel(name: "flutter_jscore", binaryMessenger: registrar.messenger)
7 | let instance = FlutterJscorePlugin()
8 | registrar.addMethodCallDelegate(instance, channel: channel)
9 | }
10 |
11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
12 | switch call.method {
13 | case "getPlatformVersion":
14 | result("macOS " + ProcessInfo.processInfo.operatingSystemVersionString)
15 | default:
16 | result(FlutterMethodNotImplemented)
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/macos/flutter_jscore.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
3 | # Run `pod lib lint flutter_jscore.podspec' to validate before publishing.
4 | #
5 | Pod::Spec.new do |s|
6 | s.name = 'flutter_jscore'
7 | s.version = '0.0.1'
8 | s.summary = 'JavaScriptCore for Flutter.'
9 | s.description = <<-DESC
10 | JavaScriptCore for Flutter.
11 | DESC
12 | s.homepage = 'http://example.com'
13 | s.license = { :file => '../LICENSE' }
14 | s.author = { 'Your Company' => 'email@example.com' }
15 | s.source = { :path => '.' }
16 | s.source_files = 'Classes/**/*'
17 | s.dependency 'FlutterMacOS'
18 | s.frameworks = 'JavaScriptCore'
19 |
20 | s.platform = :osx, '10.11'
21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
22 | s.swift_version = '5.0'
23 | end
24 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "2.6.1"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.1.0"
18 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.1.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "1.2.0"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.1.0"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.15.0"
46 | fake_async:
47 | dependency: transitive
48 | description:
49 | name: fake_async
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "1.2.0"
53 | ffi:
54 | dependency: "direct main"
55 | description:
56 | name: ffi
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "1.0.0"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_test:
66 | dependency: "direct dev"
67 | description: flutter
68 | source: sdk
69 | version: "0.0.0"
70 | matcher:
71 | dependency: transitive
72 | description:
73 | name: matcher
74 | url: "https://pub.flutter-io.cn"
75 | source: hosted
76 | version: "0.12.10"
77 | meta:
78 | dependency: transitive
79 | description:
80 | name: meta
81 | url: "https://pub.flutter-io.cn"
82 | source: hosted
83 | version: "1.3.0"
84 | path:
85 | dependency: transitive
86 | description:
87 | name: path
88 | url: "https://pub.flutter-io.cn"
89 | source: hosted
90 | version: "1.8.0"
91 | sky_engine:
92 | dependency: transitive
93 | description: flutter
94 | source: sdk
95 | version: "0.0.99"
96 | source_span:
97 | dependency: transitive
98 | description:
99 | name: source_span
100 | url: "https://pub.flutter-io.cn"
101 | source: hosted
102 | version: "1.8.1"
103 | stack_trace:
104 | dependency: transitive
105 | description:
106 | name: stack_trace
107 | url: "https://pub.flutter-io.cn"
108 | source: hosted
109 | version: "1.10.0"
110 | stream_channel:
111 | dependency: transitive
112 | description:
113 | name: stream_channel
114 | url: "https://pub.flutter-io.cn"
115 | source: hosted
116 | version: "2.1.0"
117 | string_scanner:
118 | dependency: transitive
119 | description:
120 | name: string_scanner
121 | url: "https://pub.flutter-io.cn"
122 | source: hosted
123 | version: "1.1.0"
124 | term_glyph:
125 | dependency: transitive
126 | description:
127 | name: term_glyph
128 | url: "https://pub.flutter-io.cn"
129 | source: hosted
130 | version: "1.2.0"
131 | test_api:
132 | dependency: transitive
133 | description:
134 | name: test_api
135 | url: "https://pub.flutter-io.cn"
136 | source: hosted
137 | version: "0.3.0"
138 | typed_data:
139 | dependency: transitive
140 | description:
141 | name: typed_data
142 | url: "https://pub.flutter-io.cn"
143 | source: hosted
144 | version: "1.3.0"
145 | vector_math:
146 | dependency: transitive
147 | description:
148 | name: vector_math
149 | url: "https://pub.flutter-io.cn"
150 | source: hosted
151 | version: "2.1.0"
152 | sdks:
153 | dart: ">=2.12.0 <3.0.0"
154 | flutter: ">=1.24.0"
155 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_jscore
2 | description: JavaScriptCore for Flutter. The plugin provides the ability to evaluate JavaScript programs from within dart.
3 | version: 1.0.0
4 | homepage: https://github.com/xuelongqy/flutter_jscore
5 | repository: https://github.com/xuelongqy/flutter_jscore
6 | issue_tracker: https://github.com/xuelongqy/flutter_jscore/issues
7 |
8 | environment:
9 | sdk: ">=2.12.0 <3.0.0"
10 | flutter: ">=1.24.0"
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 |
16 | ffi: ^1.0.0
17 |
18 | dev_dependencies:
19 | flutter_test:
20 | sdk: flutter
21 |
22 | # For information on the generic Dart part of this file, see the
23 | # following page: https://dart.dev/tools/pub/pubspec
24 |
25 | # The following section is specific to Flutter.
26 | flutter:
27 | # This section identifies this Flutter project as a plugin project.
28 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily
29 | # be modified. They are used by the tooling to maintain consistency when
30 | # adding or updating assets for this project.
31 | #
32 | # NOTE: This new plugin description format is not supported on Flutter's
33 | # stable channel as of 1.9.1. A plugin published using this format will not
34 | # work for most clients until the next major stable release.
35 | # However, it is required in order to declare macOS support.
36 | plugin:
37 | platforms:
38 | android:
39 | package: com.knoyo.flutter_jscore
40 | pluginClass: FlutterJscorePlugin
41 | ios:
42 | pluginClass: FlutterJscorePlugin
43 | macos:
44 | pluginClass: FlutterJscorePlugin
45 | windows:
46 | pluginClass: FlutterJscorePlugin
47 | linux:
48 | pluginClass: FlutterJscorePlugin
49 |
50 | # To add assets to your plugin package, add an assets section, like this:
51 | # assets:
52 | # - images/a_dot_burr.jpeg
53 | # - images/a_dot_ham.jpeg
54 | #
55 | # For details regarding assets in packages, see
56 | # https://flutter.dev/assets-and-images/#from-packages
57 | #
58 | # An image asset can refer to one or more resolution-specific "variants", see
59 | # https://flutter.dev/assets-and-images/#resolution-aware.
60 |
61 | # To add custom fonts to your plugin package, add a fonts section here,
62 | # in this "flutter" section. Each entry in this list should have a
63 | # "family" key with the font family name, and a "fonts" key with a
64 | # list giving the asset and other descriptors for the font. For
65 | # example:
66 | # fonts:
67 | # - family: Schyler
68 | # fonts:
69 | # - asset: fonts/Schyler-Regular.ttf
70 | # - asset: fonts/Schyler-Italic.ttf
71 | # style: italic
72 | # - family: Trajan Pro
73 | # fonts:
74 | # - asset: fonts/TrajanPro.ttf
75 | # - asset: fonts/TrajanPro_Bold.ttf
76 | # weight: 700
77 | #
78 | # For details regarding fonts in packages, see
79 | # https://flutter.dev/custom-fonts/#from-packages
80 |
--------------------------------------------------------------------------------
/test/flutter_jscore_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 | import 'package:flutter_jscore/flutter_jscore.dart';
4 |
5 | void main() {
6 | const MethodChannel channel = MethodChannel('flutter_jscore');
7 |
8 | TestWidgetsFlutterBinding.ensureInitialized();
9 |
10 | setUp(() {
11 | channel.setMockMethodCallHandler((MethodCall methodCall) async {
12 | return '42';
13 | });
14 | });
15 |
16 | tearDown(() {
17 | channel.setMockMethodCallHandler(null);
18 | });
19 |
20 | test('getPlatformVersion', () async {
21 | //expect(await FlutterJscore.platformVersion, '42');
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/windows/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | set(PROJECT_NAME "flutter_jscore")
3 | project(${PROJECT_NAME} LANGUAGES CXX)
4 |
5 | # This value is used when generating builds using this plugin, so it must
6 | # not be changed
7 | set(PLUGIN_NAME "flutter_jscore_plugin")
8 |
9 | add_library(${PLUGIN_NAME} SHARED
10 | "flutter_jscore_plugin.cpp"
11 | )
12 | apply_standard_settings(${PLUGIN_NAME})
13 | set_target_properties(${PLUGIN_NAME} PROPERTIES
14 | CXX_VISIBILITY_PRESET hidden)
15 | target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
16 | target_include_directories(${PLUGIN_NAME} INTERFACE
17 | "${CMAKE_CURRENT_SOURCE_DIR}/include")
18 | target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
19 |
20 | # List of absolute paths to libraries that should be bundled with the plugin
21 | set(flutter_jscore_bundled_libraries
22 | ""
23 | PARENT_SCOPE
24 | )
25 |
--------------------------------------------------------------------------------
/windows/flutter_jscore_plugin.cpp:
--------------------------------------------------------------------------------
1 | #include "include/flutter_jscore/flutter_jscore_plugin.h"
2 |
3 | // This must be included before many other Windows headers.
4 | #include
5 |
6 | // For getPlatformVersion; remove unless needed for your plugin implementation.
7 | #include
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include