Skip to content

Commit

Permalink
Merge branch 'main' into fix/transition_and_style_error
Browse files Browse the repository at this point in the history
  • Loading branch information
andycall authored Oct 25, 2023
2 parents c284e82 + 911f331 commit d4f1920
Show file tree
Hide file tree
Showing 159 changed files with 6,150 additions and 210 deletions.
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# These are supported funding model platforms
github: [openwebf]
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ body:
label: Affected version
description: Please specify which version of webf you are using.
placeholder: 0.12.0 or main
- type: input
validations:
required: true
attributes:
label: Flutter versions
description: Please specify which version of flutter you are using.
placeholder: 3.13.5

- type: checkboxes
validations:
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy website content to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main", "feat/website"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- uses: actions/setup-node@v2
with:
node-version: "18.12.1"
- name: Build the Docs
run: |
cd website
npm i
npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload entire repository
path: './website/build'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
2 changes: 1 addition & 1 deletion .github/workflows/example_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
env:
nodeVersion: "16"
cmakeVersion: "3.26.3"
flutterVersion: "3.10.5"
flutterVersion: "3.13.5"

jobs:
build_windows-app_in_windows:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/integration_test_flutter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [workflow_dispatch, pull_request]
env:
nodeVersion: "16"
cmakeVersion: "3.22.x"
flutter310: "3.10.5"
flutter310: "3.13.5"

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
Expand Down Expand Up @@ -59,7 +59,7 @@ jobs:
- run: ENABLE_ASAN=true npm run build:bridge:linux
- run: node scripts/run_bridge_unit_test.js

webf_unit_test_310:
webf_unit_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -72,7 +72,7 @@ jobs:
- run: flutter doctor -v
- run: cd webf && flutter test

integration_test_f310:
integration_test:
runs-on: self-hosted
needs: [ setup, build_bridge ]
strategy:
Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,27 @@ For more details(zh_CN): https://www.zhihu.com/question/534811524/answer/2595510

[![Discord Shield](https://discordapp.com/api/guilds/1008119434688344134/widget.png?style=banner1)](https://discord.gg/DvUBtXZ5rK)

## Version requirement
## The update and maintenance policy for WebF versions

Each version of WebF will be maintained for the lifespan of three minor WebF releases. For instance, WebF 0.15.0 was released to be compatible with Flutter 3.10.x. Its support will conclude once WebF 0.18.0 is introduced. Any updates applied to versions 0.16.x and 0.17.x will be cherry-picked for the subsequent update of 0.15.x.

This ensures that users can reliably receive updates for three minor WebF versions without the necessity to upgrade the Flutter version in their app.

| WebF | Flutter |
| -------------------- | ------- |
| `>= 0.12.0 < 0.14.0` | `3.0.5` |
| `>= 0.14.0 < 0.15.0` | `3.3.10` and `3.7.3` |
| `>= 0.15.0` | `3.10.x` |
| `>= 0.15.0 < 0.16.0` | `3.10.x` |
| `>= 0.16.0 < 0.17.0` | `3.13.x` |
| `>= 0.17.0 < 0.18.0` | `3.16.x` |


<img width="817" alt="image" src="https://github.com/openwebf/webf/assets/4409743/2d5cf5a1-e670-424b-8766-324f475bbc0a">

Below is the relationship between the various Flutter and WebF versions:

<img width="627" alt="image" src="https://github.com/openwebf/webf/assets/4409743/8cace8da-ac97-4908-b970-6b52450cb4cc">


## How to use

Expand Down
68 changes: 33 additions & 35 deletions bridge/bindings/qjs/script_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ static JSValue FromNativeValue(ExecutingContext* context,
}

ScriptValue::ScriptValue(JSContext* ctx, const NativeValue& native_value, bool shared_js_value)
: ctx_(ctx),
runtime_(JS_GetRuntime(ctx)),
: runtime_(JS_GetRuntime(ctx)),
value_(FromNativeValue(ExecutingContext::From(ctx), native_value, shared_js_value)) {}

ScriptValue ScriptValue::CreateErrorObject(JSContext* ctx, const char* errmsg) {
Expand Down Expand Up @@ -135,98 +134,97 @@ ScriptValue ScriptValue::Undefined(JSContext* ctx) {

ScriptValue::ScriptValue(const ScriptValue& value) {
if (&value != this) {
value_ = JS_DupValue(ctx_, value.value_);
value_ = JS_DupValueRT(runtime_, value.value_);
}
ctx_ = value.ctx_;
runtime_ = value.runtime_;
}
ScriptValue& ScriptValue::operator=(const ScriptValue& value) {
if (&value != this) {
JS_FreeValue(ctx_, value_);
value_ = JS_DupValue(ctx_, value.value_);
JS_FreeValueRT(runtime_, value_);
value_ = JS_DupValueRT(runtime_, value.value_);
}
ctx_ = value.ctx_;
runtime_ = value.runtime_;
return *this;
}

ScriptValue::ScriptValue(ScriptValue&& value) noexcept {
if (&value != this) {
value_ = JS_DupValue(ctx_, value.value_);
value_ = JS_DupValueRT(runtime_, value.value_);
}
ctx_ = value.ctx_;
runtime_ = value.runtime_;
}
ScriptValue& ScriptValue::operator=(ScriptValue&& value) noexcept {
if (&value != this) {
JS_FreeValue(ctx_, value_);
value_ = JS_DupValue(ctx_, value.value_);
JS_FreeValueRT(runtime_, value_);
value_ = JS_DupValueRT(runtime_, value.value_);
}
ctx_ = value.ctx_;
runtime_ = value.runtime_;
return *this;
}

JSValue ScriptValue::QJSValue() const {
return value_;
}

ScriptValue ScriptValue::ToJSONStringify(ExceptionState* exception) const {
JSValue stringifyed = JS_JSONStringify(ctx_, value_, JS_NULL, JS_NULL);
ScriptValue result = ScriptValue(ctx_, stringifyed);
ScriptValue ScriptValue::ToJSONStringify(JSContext* ctx, ExceptionState* exception) const {
JSValue stringifyed = JS_JSONStringify(ctx, value_, JS_NULL, JS_NULL);
ScriptValue result = ScriptValue(ctx, stringifyed);
// JS_JSONStringify may return JS_EXCEPTION if object is not valid. Return JS_EXCEPTION and let quickjs to handle it.
if (result.IsException()) {
exception->ThrowException(ctx_, result.value_);
result = ScriptValue::Empty(ctx_);
exception->ThrowException(ctx, result.value_);
result = ScriptValue::Empty(ctx);
}
JS_FreeValue(ctx_, stringifyed);
JS_FreeValue(ctx, stringifyed);
return result;
}

AtomicString ScriptValue::ToString() const {
return {ctx_, value_};
AtomicString ScriptValue::ToString(JSContext* ctx) const {
return {ctx, value_};
}

AtomicString ScriptValue::ToLegacyDOMString() const {
AtomicString ScriptValue::ToLegacyDOMString(JSContext* ctx) const {
if (JS_IsNull(value_)) {
return AtomicString::Empty();
}
return {ctx_, value_};
return {ctx, value_};
}

std::unique_ptr<SharedNativeString> ScriptValue::ToNativeString() const {
return ToString().ToNativeString(ctx_);
std::unique_ptr<SharedNativeString> ScriptValue::ToNativeString(JSContext* ctx) const {
return ToString(ctx).ToNativeString(ctx);
}

NativeValue ScriptValue::ToNative(ExceptionState& exception_state, bool shared_js_value) const {
NativeValue ScriptValue::ToNative(JSContext* ctx, ExceptionState& exception_state, bool shared_js_value) const {
int8_t tag = JS_VALUE_GET_TAG(value_);

switch (tag) {
case JS_TAG_NULL:
case JS_TAG_UNDEFINED:
return Native_NewNull();
case JS_TAG_BOOL:
return Native_NewBool(JS_ToBool(ctx_, value_));
return Native_NewBool(JS_ToBool(ctx, value_));
case JS_TAG_FLOAT64: {
double v;
JS_ToFloat64(ctx_, &v, value_);
JS_ToFloat64(ctx, &v, value_);
return Native_NewFloat64(v);
}
case JS_TAG_INT: {
int32_t v;
JS_ToInt32(ctx_, &v, value_);
JS_ToInt32(ctx, &v, value_);
return Native_NewInt64(v);
}
case JS_TAG_STRING:
// NativeString owned by NativeValue will be freed by users.
return NativeValueConverter<NativeTypeString>::ToNativeValue(ctx_, ToString());
return NativeValueConverter<NativeTypeString>::ToNativeValue(ctx, ToString(ctx));
case JS_TAG_OBJECT: {
if (JS_IsArray(ctx_, value_)) {
std::vector<ScriptValue> values =
Converter<IDLSequence<IDLAny>>::FromValue(ctx_, value_, ASSERT_NO_EXCEPTION());
if (JS_IsArray(ctx, value_)) {
std::vector<ScriptValue> values = Converter<IDLSequence<IDLAny>>::FromValue(ctx, value_, ASSERT_NO_EXCEPTION());
auto* result = new NativeValue[values.size()];
for (int i = 0; i < values.size(); i++) {
result[i] = values[i].ToNative(exception_state, shared_js_value);
result[i] = values[i].ToNative(ctx, exception_state, shared_js_value);
}
return Native_NewList(values.size(), result);
} else if (JS_IsObject(value_)) {
if (QJSEventTarget::HasInstance(ExecutingContext::From(ctx_), value_)) {
if (QJSEventTarget::HasInstance(ExecutingContext::From(ctx), value_)) {
auto* event_target = toScriptWrappable<EventTarget>(value_);
return Native_NewPtr(JSPointerType::NativeBindingObject, event_target->bindingObject());
}
Expand All @@ -235,7 +233,7 @@ NativeValue ScriptValue::ToNative(ExceptionState& exception_state, bool shared_j
return Native_NewPtr(JSPointerType::Others, JS_VALUE_GET_PTR(value_));
}

return NativeValueConverter<NativeTypeJSON>::ToNativeValue(*this, exception_state);
return NativeValueConverter<NativeTypeJSON>::ToNativeValue(ctx, *this, exception_state);
}
}
default:
Expand Down
25 changes: 11 additions & 14 deletions bridge/bindings/qjs/script_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ class ScriptValue final {
// Create an undefined ScriptValue;
static ScriptValue Undefined(JSContext* ctx);
// Wrap an Quickjs JSValue to ScriptValue.
explicit ScriptValue(JSContext* ctx, JSValue value)
: ctx_(ctx), value_(JS_DupValue(ctx, value)), runtime_(JS_GetRuntime(ctx)){};
explicit ScriptValue(JSContext* ctx, JSValue value) : value_(JS_DupValue(ctx, value)), runtime_(JS_GetRuntime(ctx)){};
explicit ScriptValue(JSContext* ctx, const AtomicString& value)
: ctx_(ctx), value_(JS_AtomToString(ctx, value.Impl())), runtime_(JS_GetRuntime(ctx)){};
: value_(JS_AtomToString(ctx, value.Impl())), runtime_(JS_GetRuntime(ctx)){};
explicit ScriptValue(JSContext* ctx, const SharedNativeString* string)
: ctx_(ctx), value_(JS_NewUnicodeString(ctx, string->string(), string->length())), runtime_(JS_GetRuntime(ctx)) {}
explicit ScriptValue(JSContext* ctx, double v)
: ctx_(ctx), value_(JS_NewFloat64(ctx, v)), runtime_(JS_GetRuntime(ctx)) {}
explicit ScriptValue(JSContext* ctx) : ctx_(ctx), runtime_(JS_GetRuntime(ctx)){};
: value_(JS_NewUnicodeString(ctx, string->string(), string->length())), runtime_(JS_GetRuntime(ctx)) {}
explicit ScriptValue(JSContext* ctx, double v) : value_(JS_NewFloat64(ctx, v)), runtime_(JS_GetRuntime(ctx)) {}
explicit ScriptValue(JSContext* ctx) : runtime_(JS_GetRuntime(ctx)){};
explicit ScriptValue(JSContext* ctx, const NativeValue& native_value, bool shared_js_value = false);
ScriptValue() = default;

Expand All @@ -59,15 +57,15 @@ class ScriptValue final {
ScriptValue(ScriptValue&& value) noexcept;
ScriptValue& operator=(ScriptValue&& value) noexcept;

~ScriptValue() { JS_FreeValue(ctx_, value_); };
~ScriptValue() { JS_FreeValueRT(runtime_, value_); };

JSValue QJSValue() const;
// Create a new ScriptValue from call JSON.stringify to current value.
ScriptValue ToJSONStringify(ExceptionState* exception) const;
AtomicString ToString() const;
AtomicString ToLegacyDOMString() const;
std::unique_ptr<SharedNativeString> ToNativeString() const;
NativeValue ToNative(ExceptionState& exception_state, bool shared_js_value = false) const;
ScriptValue ToJSONStringify(JSContext* ctx, ExceptionState* exception) const;
AtomicString ToString(JSContext* ctx) const;
AtomicString ToLegacyDOMString(JSContext* ctx) const;
std::unique_ptr<SharedNativeString> ToNativeString(JSContext* ctx) const;
NativeValue ToNative(JSContext* ctx, ExceptionState& exception_state, bool shared_js_value = false) const;

bool IsException() const;
bool IsEmpty() const;
Expand All @@ -80,7 +78,6 @@ class ScriptValue final {
void Trace(GCVisitor* visitor) const;

private:
JSContext* ctx_{nullptr};
JSRuntime* runtime_{nullptr};
JSValue value_{JS_NULL};
};
Expand Down
6 changes: 3 additions & 3 deletions bridge/bindings/qjs/script_value_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST(ScriptValue, ToString) {
TestScriptValue([](JSContext* ctx) {
std::string code = "{\"name\": 1}";
ScriptValue json = ScriptValue::CreateJsonObject(ctx, code.c_str(), code.size());
AtomicString string = json.ToString();
AtomicString string = json.ToString(ctx);
EXPECT_STREQ(string.ToStdString(ctx).c_str(), "[object Object]");
});
}
Expand All @@ -63,7 +63,7 @@ TEST(ScriptValue, CopyAssignment) {
};
P p;
p.value = json;
EXPECT_STREQ(p.value.ToJSONStringify(nullptr).ToString().ToStdString(ctx).c_str(), code.c_str());
EXPECT_STREQ(p.value.ToJSONStringify(ctx, nullptr).ToString(ctx).ToStdString(ctx).c_str(), code.c_str());
});
}

Expand All @@ -75,6 +75,6 @@ TEST(ScriptValue, MoveAssignment) {
other = ScriptValue::CreateJsonObject(ctx, code.c_str(), code.size());
}

EXPECT_STREQ(other.ToJSONStringify(nullptr).ToString().ToStdString(ctx).c_str(), "{\"name\":1}");
EXPECT_STREQ(other.ToJSONStringify(ctx, nullptr).ToString(ctx).ToStdString(ctx).c_str(), "{\"name\":1}");
});
}
4 changes: 2 additions & 2 deletions bridge/core/binding_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ ScriptValue BindingObject::AnonymousFunctionCallback(JSContext* ctx,
ExceptionState exception_state;

for (int i = 0; i < argc; i++) {
arguments.emplace_back(argv[i].ToNative(exception_state));
arguments.emplace_back(argv[i].ToNative(ctx, exception_state));
}

if (exception_state.HasException()) {
Expand Down Expand Up @@ -217,7 +217,7 @@ ScriptValue BindingObject::AnonymousAsyncFunctionCallback(JSContext* ctx,
ExceptionState exception_state;

for (int i = 0; i < argc; i++) {
arguments.emplace_back(argv[i].ToNative(exception_state));
arguments.emplace_back(argv[i].ToNative(ctx, exception_state));
}

event_target->InvokeBindingMethod(BindingMethodCallOperations::kAsyncAnonymousFunction, argc + 4, arguments.data(),
Expand Down
7 changes: 4 additions & 3 deletions bridge/core/css/computed_css_style_declaration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ ScriptValue ComputedCssStyleDeclaration::item(const AtomicString& key, Exception
bool ComputedCssStyleDeclaration::SetItem(const AtomicString& key,
const ScriptValue& value,
ExceptionState& exception_state) {
NativeValue arguments[] = {NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), key),
NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), value.ToLegacyDOMString())};
NativeValue arguments[] = {
NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), key),
NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), value.ToLegacyDOMString(ctx()))};
InvokeBindingMethod(binding_call_methods::ksetProperty, 2, arguments, exception_state);
return true;
}
Expand All @@ -45,7 +46,7 @@ int64_t ComputedCssStyleDeclaration::length() const {
}

AtomicString ComputedCssStyleDeclaration::getPropertyValue(const AtomicString& key, ExceptionState& exception_state) {
return item(key, exception_state).ToLegacyDOMString();
return item(key, exception_state).ToLegacyDOMString(ctx());
}

void ComputedCssStyleDeclaration::setProperty(const AtomicString& key,
Expand Down
Loading

0 comments on commit d4f1920

Please sign in to comment.