diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 4dc96406..00000000 Binary files a/.DS_Store and /dev/null differ diff --git a/Android/app/src/main/java/pub/doric/demo/DemoActivity.java b/Android/app/src/main/java/pub/doric/demo/DemoActivity.java index 1265d56d..6703c846 100644 --- a/Android/app/src/main/java/pub/doric/demo/DemoActivity.java +++ b/Android/app/src/main/java/pub/doric/demo/DemoActivity.java @@ -18,7 +18,6 @@ package pub.doric.demo; import android.os.Bundle; import android.view.KeyEvent; import android.view.ViewGroup; -import android.widget.FrameLayout; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -30,6 +29,7 @@ import org.greenrobot.eventbus.ThreadMode; import pub.doric.DoricContext; import pub.doric.DoricContextManager; +import pub.doric.DoricPanel; import pub.doric.devkit.DoricContextDebuggable; import pub.doric.devkit.event.EnterDebugEvent; import pub.doric.devkit.event.QuitDebugEvent; @@ -52,14 +52,12 @@ public class DemoActivity extends AppCompatActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); String source = getIntent().getStringExtra("source"); - FrameLayout frameLayout = new FrameLayout(this); - addContentView(frameLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + DoricPanel doricPanel = new DoricPanel(this); + addContentView(doricPanel, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - doricContext = DoricContext.create(this, DoricUtils.readAssetFile("demo/" + source), source); + doricPanel.config(DoricUtils.readAssetFile("demo/" + source), source); + doricContext = doricPanel.getDoricContext(); doricContextDebuggable = new DoricContextDebuggable(doricContext); - doricContext.init(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - doricContext.getRootNode().setRootView(frameLayout); - sensorHelper = new SensorManagerHelper(this); sensorHelper.setOnShakeListener(new SensorManagerHelper.OnShakeListener() { @Override @@ -73,18 +71,6 @@ public class DemoActivity extends AppCompatActivity { }); } - @Override - protected void onResume() { - super.onResume(); - doricContext.onShow(); - } - - @Override - protected void onPause() { - super.onPause(); - doricContext.onHidden(); - } - @Override public void onAttachedToWindow() { super.onAttachedToWindow(); @@ -95,7 +81,6 @@ public class DemoActivity extends AppCompatActivity { @Override protected void onDestroy() { super.onDestroy(); - doricContext.teardown(); EventBus.getDefault().unregister(this); sensorHelper.stop(); } diff --git a/Android/app/src/main/java/pub/doric/demo/MainActivity.java b/Android/app/src/main/java/pub/doric/demo/MainActivity.java index 59a6ce2d..a370254c 100644 --- a/Android/app/src/main/java/pub/doric/demo/MainActivity.java +++ b/Android/app/src/main/java/pub/doric/demo/MainActivity.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import pub.doric.DoricActivity; import pub.doric.utils.DoricUtils; public class MainActivity extends AppCompatActivity { @@ -89,6 +90,13 @@ public class MainActivity extends AppCompatActivity { tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + if (data[position].contains("NavigatorDemo")) { + Intent intent = new Intent(tv.getContext(), DoricActivity.class); + intent.putExtra("scheme", "assets://demo/" + data[position]); + intent.putExtra("alias", data[position]); + tv.getContext().startActivity(intent); + return; + } Intent intent = new Intent(tv.getContext(), DemoActivity.class); intent.putExtra("source", data[position]); tv.getContext().startActivity(intent); diff --git a/Android/doric/src/main/AndroidManifest.xml b/Android/doric/src/main/AndroidManifest.xml index cf6aef36..ec029524 100644 --- a/Android/doric/src/main/AndroidManifest.xml +++ b/Android/doric/src/main/AndroidManifest.xml @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + + + + + + + + diff --git a/Android/doric/src/main/java/pub/doric/DoricActivity.java b/Android/doric/src/main/java/pub/doric/DoricActivity.java new file mode 100644 index 00000000..ad225b6d --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/DoricActivity.java @@ -0,0 +1,53 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +/** + * @Description: pub.doric.demo + * @Author: pengfei.zhou + * @CreateDate: 2019-11-19 + */ +public class DoricActivity extends AppCompatActivity { + private DoricFragment doricFragment; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.doric_activity); + if (savedInstanceState == null) { + String scheme = getIntent().getStringExtra("scheme"); + String alias = getIntent().getStringExtra("alias"); + doricFragment = DoricFragment.newInstance(scheme, alias); + getSupportFragmentManager().beginTransaction() + .add(R.id.container, doricFragment) + .commit(); + } + } + + @Override + public void onBackPressed() { + if (doricFragment.canPop()) { + doricFragment.pop(); + } else { + super.onBackPressed(); + } + } +} diff --git a/Android/doric/src/main/java/pub/doric/DoricContext.java b/Android/doric/src/main/java/pub/doric/DoricContext.java index f9152e21..63fd5856 100644 --- a/Android/doric/src/main/java/pub/doric/DoricContext.java +++ b/Android/doric/src/main/java/pub/doric/DoricContext.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Map; import pub.doric.async.AsyncResult; +import pub.doric.navigator.IDoricNavigator; import pub.doric.plugin.DoricJavaPlugin; import pub.doric.shader.RootNode; import pub.doric.utils.DoricConstant; @@ -66,7 +67,7 @@ public class DoricContext { return doricContext; } - public void init(int width, int height) { + public void init(float width, float height) { this.initParams = new JSONBuilder() .put("width", width) .put("height", height).toJSONObject(); @@ -148,4 +149,14 @@ public class DoricContext { public void onHidden() { callEntity(DoricConstant.DORIC_ENTITY_HIDDEN); } + + private IDoricNavigator doricNavigator; + + public void setDoricNavigator(IDoricNavigator doricNavigator) { + this.doricNavigator = doricNavigator; + } + + public IDoricNavigator getDoricNavigator() { + return this.doricNavigator; + } } diff --git a/Android/doric/src/main/java/pub/doric/DoricFragment.java b/Android/doric/src/main/java/pub/doric/DoricFragment.java new file mode 100644 index 00000000..e64117b3 --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/DoricFragment.java @@ -0,0 +1,84 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import pub.doric.navigator.IDoricNavigator; + +/** + * @Description: pub.doric + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public class DoricFragment extends Fragment implements IDoricNavigator { + + public static DoricFragment newInstance(String scheme, String alias) { + Bundle args = new Bundle(); + args.putString("scheme", scheme); + args.putString("alias", alias); + DoricFragment fragment = new DoricFragment(); + fragment.setArguments(args); + return fragment; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.doric_fragment, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Bundle argument = getArguments(); + if (argument != null) { + String alias = argument.getString("alias"); + String scheme = argument.getString("scheme"); + push(scheme, alias); + } + } + + @Override + public void push(String scheme, String alias) { + getChildFragmentManager().beginTransaction() + .add(R.id.root, DoricPanelFragment.newInstance(scheme, alias)) + .addToBackStack(scheme) + .commit(); + } + + @Override + public void pop() { + if (canPop()) { + getChildFragmentManager().popBackStack(); + } else { + if (getActivity() != null) { + getActivity().finish(); + } + } + } + + public boolean canPop() { + return getChildFragmentManager().getBackStackEntryCount() > 1; + } +} diff --git a/Android/doric/src/main/java/pub/doric/DoricPanel.java b/Android/doric/src/main/java/pub/doric/DoricPanel.java index 693c43c4..a9e578c5 100644 --- a/Android/doric/src/main/java/pub/doric/DoricPanel.java +++ b/Android/doric/src/main/java/pub/doric/DoricPanel.java @@ -16,40 +16,43 @@ package pub.doric; import android.content.Context; -import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; import android.util.AttributeSet; import android.widget.FrameLayout; +import pub.doric.utils.DoricUtils; + /** * @Description: Doric * @Author: pengfei.zhou * @CreateDate: 2019-07-18 */ -public class DoricPanel extends FrameLayout { +public class DoricPanel extends FrameLayout implements LifecycleObserver { private DoricContext mDoricContext; public DoricPanel(@NonNull Context context) { - super(context); + this(context, null); } public DoricPanel(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); } public DoricPanel(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); + if (getContext() instanceof LifecycleOwner) { + ((LifecycleOwner) getContext()).getLifecycle().addObserver(this); + } } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public DoricPanel(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } public void config(String script, String alias) { DoricContext doricContext = DoricContext.create(getContext(), script, alias); @@ -58,6 +61,14 @@ public class DoricPanel extends FrameLayout { public void config(DoricContext doricContext) { mDoricContext = doricContext; + mDoricContext.getRootNode().setRootView(this); + if (getMeasuredState() != 0) { + mDoricContext.init(DoricUtils.px2dp(getMeasuredWidth()), DoricUtils.px2dp(getMeasuredHeight())); + } + if (getContext() instanceof LifecycleOwner + && ((LifecycleOwner) getContext()).getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { + mDoricContext.onShow(); + } } @Override @@ -68,4 +79,35 @@ public class DoricPanel extends FrameLayout { public DoricContext getDoricContext() { return mDoricContext; } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (oldw != w || oldh != h) { + if (mDoricContext != null) { + mDoricContext.init(DoricUtils.px2dp(w), DoricUtils.px2dp(h)); + } + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) + public void onActivityResume() { + if (mDoricContext != null) { + mDoricContext.onShow(); + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) + public void onActivityPause() { + if (mDoricContext != null) { + mDoricContext.onHidden(); + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + public void onActivityDestroy() { + if (mDoricContext != null) { + mDoricContext.teardown(); + } + } } diff --git a/Android/doric/src/main/java/pub/doric/DoricPanelFragment.java b/Android/doric/src/main/java/pub/doric/DoricPanelFragment.java new file mode 100644 index 00000000..c25b033f --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/DoricPanelFragment.java @@ -0,0 +1,88 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import pub.doric.async.AsyncResult; +import pub.doric.loader.DoricJSLoaderManager; +import pub.doric.navigator.IDoricNavigator; +import pub.doric.utils.DoricLog; + +/** + * @Description: pub.doric + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public class DoricPanelFragment extends Fragment { + private DoricPanel doricPanel; + + public static DoricPanelFragment newInstance(String scheme, String alias) { + Bundle args = new Bundle(); + args.putString("scheme", scheme); + args.putString("alias", alias); + DoricPanelFragment fragment = new DoricPanelFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + doricPanel = (DoricPanel) inflater.inflate(R.layout.doric_framgent_panel, container, false); + return doricPanel; + } + + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Bundle argument = getArguments(); + if (argument == null) { + DoricLog.e("DoricPanelFragment argument is null"); + return; + } + final String alias = argument.getString("alias"); + String scheme = argument.getString("scheme"); + DoricJSLoaderManager.getInstance().loadJSBundle(scheme).setCallback(new AsyncResult.Callback() { + @Override + public void onResult(String result) { + doricPanel.config(result, alias); + DoricContext context = doricPanel.getDoricContext(); + Fragment fragment = getParentFragment(); + if (fragment instanceof IDoricNavigator) { + context.setDoricNavigator((IDoricNavigator) fragment); + } + } + + @Override + public void onError(Throwable t) { + DoricLog.e("DoricPanelFragment load JS error:" + t.getLocalizedMessage()); + } + + @Override + public void onFinish() { + + } + }); + } +} diff --git a/Android/doric/src/main/java/pub/doric/DoricRegistry.java b/Android/doric/src/main/java/pub/doric/DoricRegistry.java index bbcd374a..2059d18b 100644 --- a/Android/doric/src/main/java/pub/doric/DoricRegistry.java +++ b/Android/doric/src/main/java/pub/doric/DoricRegistry.java @@ -17,6 +17,10 @@ package pub.doric; import android.text.TextUtils; +import pub.doric.loader.DoricAssetJSLoader; +import pub.doric.loader.DoricHttpJSLoader; +import pub.doric.loader.IDoricJSLoader; +import pub.doric.plugin.NavigatorPlugin; import pub.doric.plugin.NetworkPlugin; import pub.doric.plugin.ShaderPlugin; import pub.doric.plugin.StoragePlugin; @@ -36,6 +40,7 @@ import pub.doric.utils.DoricMetaInfo; import pub.doric.plugin.DoricJavaPlugin; import pub.doric.plugin.ModalPlugin; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -43,15 +48,22 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** - * @Description: com.github.penfeizhou.doric + * @Description: pub.doric * @Author: pengfei.zhou * @CreateDate: 2019-07-20 */ public class DoricRegistry { private static Map bundles = new ConcurrentHashMap<>(); + private static Set doricLibraries = new HashSet<>(); + private static Set jsLoaders = new HashSet<>(); + + static { + addJSLoader(new DoricAssetJSLoader()); + addJSLoader(new DoricHttpJSLoader()); + } + private Map> pluginInfoMap = new HashMap<>(); private Map> nodeInfoMap = new HashMap<>(); - private static Set doricLibraries = new HashSet<>(); private static void initRegistry(DoricRegistry doricRegistry) { for (DoricLibrary library : doricLibraries) { @@ -69,6 +81,7 @@ public class DoricRegistry { this.registerNativePlugin(ModalPlugin.class); this.registerNativePlugin(NetworkPlugin.class); this.registerNativePlugin(StoragePlugin.class); + this.registerNativePlugin(NavigatorPlugin.class); this.registerViewNode(RootNode.class); this.registerViewNode(TextNode.class); this.registerViewNode(ImageNode.class); @@ -112,4 +125,12 @@ public class DoricRegistry { public String acquireJSBundle(String name) { return bundles.get(name); } + + public static void addJSLoader(IDoricJSLoader jsLoader) { + jsLoaders.add(jsLoader); + } + + public static Collection getJSLoaders() { + return jsLoaders; + } } diff --git a/Android/doric/src/main/java/pub/doric/async/AsyncResult.java b/Android/doric/src/main/java/pub/doric/async/AsyncResult.java index 0b06f9ee..2f6af37a 100644 --- a/Android/doric/src/main/java/pub/doric/async/AsyncResult.java +++ b/Android/doric/src/main/java/pub/doric/async/AsyncResult.java @@ -26,6 +26,13 @@ public class AsyncResult { private Callback callback = null; + public AsyncResult() { + } + + public AsyncResult(R r) { + this.result = r; + } + public void setResult(R result) { this.result = result; if (this.callback != null) { diff --git a/Android/doric/src/main/java/pub/doric/loader/DoricAssetJSLoader.java b/Android/doric/src/main/java/pub/doric/loader/DoricAssetJSLoader.java new file mode 100644 index 00000000..2352d971 --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/loader/DoricAssetJSLoader.java @@ -0,0 +1,36 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.loader; + +import pub.doric.async.AsyncResult; +import pub.doric.utils.DoricUtils; + +/** + * @Description: handle "assets://asset-file-path" + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public class DoricAssetJSLoader implements IDoricJSLoader { + @Override + public boolean filter(String scheme) { + return scheme.startsWith("assets"); + } + + @Override + public AsyncResult request(String scheme) { + return new AsyncResult<>(DoricUtils.readAssetFile(scheme.substring("assets://".length()))); + } +} diff --git a/Android/doric/src/main/java/pub/doric/loader/DoricHttpJSLoader.java b/Android/doric/src/main/java/pub/doric/loader/DoricHttpJSLoader.java new file mode 100644 index 00000000..ca3732a6 --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/loader/DoricHttpJSLoader.java @@ -0,0 +1,64 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.loader; + +import com.bumptech.glide.RequestBuilder; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import pub.doric.async.AsyncResult; + +/** + * @Description: handle like "https://xxxx.js" + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public class DoricHttpJSLoader implements IDoricJSLoader { + private OkHttpClient okHttpClient = new OkHttpClient(); + + @Override + public boolean filter(String scheme) { + return scheme.startsWith("http"); + } + + @Override + public AsyncResult request(String scheme) { + final AsyncResult ret = new AsyncResult<>(); + okHttpClient.newCall(new Request.Builder().url(scheme).build()).enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + ret.setError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + try { + ret.setResult(response.body().string()); + } catch (Exception e) { + ret.setError(e); + } + } + }); + return ret; + } +} diff --git a/Android/doric/src/main/java/pub/doric/loader/DoricJSLoaderManager.java b/Android/doric/src/main/java/pub/doric/loader/DoricJSLoaderManager.java new file mode 100644 index 00000000..f3c01898 --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/loader/DoricJSLoaderManager.java @@ -0,0 +1,51 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.loader; + + +import java.util.Collection; + +import pub.doric.DoricRegistry; +import pub.doric.async.AsyncResult; + +/** + * @Description: pub.doric + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public class DoricJSLoaderManager { + private DoricJSLoaderManager() { + } + + private static class Inner { + private static final DoricJSLoaderManager sInstance = new DoricJSLoaderManager(); + } + + public static DoricJSLoaderManager getInstance() { + return Inner.sInstance; + } + + public AsyncResult loadJSBundle(String scheme) { + Collection jsLoaders = DoricRegistry.getJSLoaders(); + for (IDoricJSLoader jsLoader : jsLoaders) { + if (jsLoader.filter(scheme)) { + return jsLoader.request(scheme); + } + } + return new AsyncResult<>(""); + } + +} diff --git a/Android/doric/src/main/java/pub/doric/loader/IDoricJSLoader.java b/Android/doric/src/main/java/pub/doric/loader/IDoricJSLoader.java new file mode 100644 index 00000000..c26f453f --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/loader/IDoricJSLoader.java @@ -0,0 +1,29 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.loader; + +import pub.doric.async.AsyncResult; + +/** + * @Description: pub.doric + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public interface IDoricJSLoader { + boolean filter(String scheme); + + AsyncResult request(String scheme); +} diff --git a/Android/doric/src/main/java/pub/doric/navigator/IDoricNavigator.java b/Android/doric/src/main/java/pub/doric/navigator/IDoricNavigator.java new file mode 100644 index 00000000..e260cd5f --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/navigator/IDoricNavigator.java @@ -0,0 +1,27 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.navigator; + +/** + * @Description: pub.doric.navigator + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +public interface IDoricNavigator { + void push(String scheme, String alias); + + void pop(); +} diff --git a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java index 0d8cfd62..18dcd2f9 100644 --- a/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java +++ b/Android/doric/src/main/java/pub/doric/plugin/ModalPlugin.java @@ -32,7 +32,6 @@ import pub.doric.extension.bridge.DoricPromise; import pub.doric.utils.DoricUtils; import pub.doric.utils.ThreadMode; -import com.github.pengfeizhou.jscore.ArchiveException; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; @@ -51,7 +50,7 @@ public class ModalPlugin extends DoricJavaPlugin { } @DoricMethod(thread = ThreadMode.UI) - public void toast(JSDecoder decoder, DoricPromise promise) { + public void toast(JSDecoder decoder) { try { JSObject jsObject = decoder.decode().asObject(); String msg = jsObject.getProperty("msg").asString().value(); diff --git a/Android/doric/src/main/java/pub/doric/plugin/NavigatorPlugin.java b/Android/doric/src/main/java/pub/doric/plugin/NavigatorPlugin.java new file mode 100644 index 00000000..372529ec --- /dev/null +++ b/Android/doric/src/main/java/pub/doric/plugin/NavigatorPlugin.java @@ -0,0 +1,61 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.plugin; + +import com.github.pengfeizhou.jscore.ArchiveException; +import com.github.pengfeizhou.jscore.JSDecoder; +import com.github.pengfeizhou.jscore.JSObject; + +import pub.doric.DoricContext; +import pub.doric.extension.bridge.DoricMethod; +import pub.doric.extension.bridge.DoricPlugin; +import pub.doric.navigator.IDoricNavigator; +import pub.doric.utils.ThreadMode; + +/** + * @Description: pub.doric.plugin + * @Author: pengfei.zhou + * @CreateDate: 2019-11-23 + */ +@DoricPlugin(name = "navigator") +public class NavigatorPlugin extends DoricJavaPlugin { + public NavigatorPlugin(DoricContext doricContext) { + super(doricContext); + } + + @DoricMethod(thread = ThreadMode.UI) + public void push(JSDecoder jsDecoder) { + IDoricNavigator navigator = getDoricContext().getDoricNavigator(); + if (navigator != null) { + try { + JSObject jsObject = jsDecoder.decode().asObject(); + navigator.push(jsObject.getProperty("scheme").asString().value(), + jsObject.getProperty("alias").asString().value() + ); + } catch (ArchiveException e) { + e.printStackTrace(); + } + } + } + + @DoricMethod(thread = ThreadMode.UI) + public void pop() { + IDoricNavigator navigator = getDoricContext().getDoricNavigator(); + if (navigator != null) { + navigator.pop(); + } + } +} diff --git a/Android/doric/src/main/res/layout/doric_activity.xml b/Android/doric/src/main/res/layout/doric_activity.xml new file mode 100644 index 00000000..54b71a1b --- /dev/null +++ b/Android/doric/src/main/res/layout/doric_activity.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/Android/doric/src/main/res/layout/doric_fragment.xml b/Android/doric/src/main/res/layout/doric_fragment.xml new file mode 100644 index 00000000..7af124c8 --- /dev/null +++ b/Android/doric/src/main/res/layout/doric_fragment.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Android/doric/src/main/res/layout/doric_framgent_panel.xml b/Android/doric/src/main/res/layout/doric_framgent_panel.xml new file mode 100644 index 00000000..eab7ed13 --- /dev/null +++ b/Android/doric/src/main/res/layout/doric_framgent_panel.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/demo/index.ts b/demo/index.ts index 36729e73..3b1dace6 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -10,4 +10,5 @@ export default [ 'src/ModalDemo', 'src/NetworkDemo', 'src/StorageDemo', + 'src/NavigatorDemo', ] \ No newline at end of file diff --git a/demo/src/NavigatorDemo.ts b/demo/src/NavigatorDemo.ts new file mode 100644 index 00000000..62d09ccb --- /dev/null +++ b/demo/src/NavigatorDemo.ts @@ -0,0 +1,50 @@ +import { Panel, scroller, vlayout, text, layoutConfig, LayoutSpec, Color, gravity, IVLayout, Group, IText, navigator } from "doric"; +import { colors, label } from "./utils"; +@Entry +class NaivgatorDemo extends Panel { + build(root: Group) { + scroller(vlayout([ + text({ + text: "Navigator Demo", + layoutConfig: layoutConfig().w(LayoutSpec.AT_MOST), + textSize: 30, + textColor: Color.WHITE, + bgColor: colors[1], + textAlignment: gravity().center(), + height: 50, + }), + ...['Counter', 'EffectsDemo', 'ImageDemo', 'LayoutDemo', + 'ListDemo', 'ModalDemo', 'NavigatorDemo', + 'NetworkDemo', 'ScrollerDemo', 'SliderDemo', 'Snake', 'StorageDemo'].map(e => + label(e).apply({ + height: 50, + bgColor: colors[0], + textSize: 30, + textColor: Color.WHITE, + layoutConfig: layoutConfig().exactly().w(LayoutSpec.AT_MOST), + onClick: () => { + navigator(context).push(`assets://demo/${e}.js`, `${e}.js`) + }, + } as IText) + ), + label('POP').apply({ + width: 200, + height: 50, + bgColor: colors[0], + textSize: 30, + textColor: Color.WHITE, + layoutConfig: layoutConfig().exactly(), + onClick: () => { + navigator(context).pop() + }, + } as IText), + ]).apply({ + layoutConfig: layoutConfig().atmost().h(LayoutSpec.WRAP_CONTENT), + gravity: gravity().center(), + space: 10, + } as IVLayout)).apply({ + layoutConfig: layoutConfig().atmost(), + }).in(root) + } + +} \ No newline at end of file diff --git a/iOS/Example/Example/DemoVC.m b/iOS/Example/Example/DemoVC.m index 38e215e1..02f7f354 100644 --- a/iOS/Example/Example/DemoVC.m +++ b/iOS/Example/Example/DemoVC.m @@ -4,16 +4,10 @@ // #import "DemoVC.h" -#import "DoricContext.h" -#import "DoricLayouts.h" -#import "DoricExtensions.h" -#import "DoricRootNode.h" -#import "DoricLocalServer.h" +#import "Doric.h" @interface DemoVC () @property(nonatomic, copy) NSString *filePath; -@property(nonatomic, strong) DoricContext *doricContext; -//@property(nonatomic, strong) DoricLocalServer *localServer; @end @implementation DemoVC @@ -31,21 +25,15 @@ - (void)viewDidLoad { NSString *demoPath = [path stringByAppendingPathComponent:@"demo"]; NSString *fullPath = [demoPath stringByAppendingPathComponent:self.filePath]; NSString *jsContent = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:nil]; - self.doricContext = [[DoricContext alloc] initWithScript:jsContent source:self.filePath]; - [self.doricContext.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) { - it.backgroundColor = [UIColor whiteColor]; - it.layoutConfig = [[DoricLayoutConfig alloc] - initWithWidth:DoricLayoutAtMost - height:DoricLayoutAtMost - margin:DoricMarginMake(0, 88, 0, 0) - ]; + DoricPanel *panel = [DoricPanel new]; + [panel.view also:^(UIView *it) { + it.width = self.view.width; + it.height = self.view.height - 88; it.top = 88; [self.view addSubview:it]; - }]]; - [self.doricContext initContextWithWidth:self.view.width height:self.view.height]; -// [self.doricContext.driver connectDevKit:@"ws://192.168.11.38:7777"]; -// self.localServer = [[DoricLocalServer alloc] init]; -// [self.localServer startWithPort:8910]; + }]; + [self addChildViewController:panel]; + [panel config:jsContent alias:self.filePath]; } @end \ No newline at end of file diff --git a/iOS/Example/Example/ViewController.m b/iOS/Example/Example/ViewController.m index 8acce53f..6110d39c 100644 --- a/iOS/Example/Example/ViewController.m +++ b/iOS/Example/Example/ViewController.m @@ -58,8 +58,16 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self.navigationController pushViewController:[QRScanViewController new] animated:NO]; return; } - DemoVC *demoVC = [[DemoVC alloc] initWithPath:self.demoFilePaths[(NSUInteger) indexPath.row]]; - [self.navigationController pushViewController:demoVC animated:NO]; + NSString *file = self.demoFilePaths[(NSUInteger) indexPath.row]; + if ([file containsString:@"NavigatorDemo"]) { + DoricViewController *doricViewController = [[DoricViewController alloc] + initWithScheme:[NSString stringWithFormat:@"assets://demo/%@", file] + alias:self.demoFilePaths[(NSUInteger) indexPath.row]]; + [self.navigationController pushViewController:doricViewController animated:NO]; + } else { + DemoVC *demoVC = [[DemoVC alloc] initWithPath:file]; + [self.navigationController pushViewController:demoVC animated:NO]; + } } @end diff --git a/iOS/Pod/Classes/Doric.h b/iOS/Pod/Classes/Doric.h index 21adbf24..9df6d257 100644 --- a/iOS/Pod/Classes/Doric.h +++ b/iOS/Pod/Classes/Doric.h @@ -19,4 +19,8 @@ #import "DoricViewNode.h" #import "DoricRootNode.h" #import "UIView+Doric.h" -#import "DoricUtil.h" \ No newline at end of file +#import "DoricUtil.h" +#import "DoricPanel.h" +#import "DoricJSLoaderManager.h" +#import "DoricNavigatorProtocol.h" +#import "DoricViewController.h" \ No newline at end of file diff --git a/iOS/Pod/Classes/DoricContext.h b/iOS/Pod/Classes/DoricContext.h index 6607ba4b..7c1bcefd 100644 --- a/iOS/Pod/Classes/DoricContext.h +++ b/iOS/Pod/Classes/DoricContext.h @@ -22,13 +22,14 @@ #import #import "DoricDriver.h" +#import "DoricNavigatorProtocol.h" NS_ASSUME_NONNULL_BEGIN @class DoricRootNode; @interface DoricContext : NSObject - +@property(nonatomic, weak) id navigator; @property(nonatomic, strong) NSString *contextId; @property(nonatomic, strong) DoricDriver *driver; @property(nonatomic, strong) NSMutableDictionary *pluginInstanceMap; diff --git a/iOS/Pod/Classes/DoricPanel.h b/iOS/Pod/Classes/DoricPanel.h new file mode 100644 index 00000000..66ad7657 --- /dev/null +++ b/iOS/Pod/Classes/DoricPanel.h @@ -0,0 +1,29 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import + +#import "DoricContext.h" +#import "DoricNavigatorProtocol.h" + +@interface DoricPanel : UIViewController +@property(nonatomic, strong) DoricContext *doricContext; + +- (void)config:(NSString *)script alias:(NSString *)alias; +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/DoricPanel.m b/iOS/Pod/Classes/DoricPanel.m new file mode 100644 index 00000000..b4cc5af1 --- /dev/null +++ b/iOS/Pod/Classes/DoricPanel.m @@ -0,0 +1,49 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricPanel.h" +#import "Doric.h" + +@implementation DoricPanel + +- (void)config:(NSString *)script alias:(NSString *)alias { + self.doricContext = [[[DoricContext alloc] initWithScript:script source:alias] also:^(DoricContext *it) { + if ([self.parentViewController conformsToProtocol:@protocol(DoricNavigatorProtocol)]) { + it.navigator = (id ) self.parentViewController; + } + [it.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) { + it.width = self.view.width; + it.height = self.view.height; + [self.view addSubview:it]; + }]]; + [it initContextWithWidth:self.view.width height:self.view.height]; + }]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self.doricContext onShow]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [self.doricContext onHidden]; +} + +@end diff --git a/iOS/Pod/Classes/DoricRegistry.m b/iOS/Pod/Classes/DoricRegistry.m index e538d993..99a0ca3b 100644 --- a/iOS/Pod/Classes/DoricRegistry.m +++ b/iOS/Pod/Classes/DoricRegistry.m @@ -35,6 +35,7 @@ #import "DoricSliderNode.h" #import "DoricSlideItemNode.h" #import "DoricStoragePlugin.h" +#import "DoricNavigatorPlugin.h" @interface DoricRegistry () @@ -61,6 +62,7 @@ - (void)innerRegister { [self registerNativePlugin:DoricModalPlugin.class withName:@"modal"]; [self registerNativePlugin:DoricNetworkPlugin.class withName:@"network"]; [self registerNativePlugin:DoricStoragePlugin.class withName:@"storage"]; + [self registerNativePlugin:DoricNavigatorPlugin.class withName:@"navigator"]; [self registerViewNode:DoricStackNode.class withName:@"Stack"]; [self registerViewNode:DoricVLayoutNode.class withName:@"VLayout"]; diff --git a/iOS/Pod/Classes/DoricViewController.h b/iOS/Pod/Classes/DoricViewController.h new file mode 100644 index 00000000..b39c3e4a --- /dev/null +++ b/iOS/Pod/Classes/DoricViewController.h @@ -0,0 +1,25 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import +#import "DoricNavigatorProtocol.h" + +@interface DoricViewController : UIViewController +- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias; +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/DoricViewController.m b/iOS/Pod/Classes/DoricViewController.m new file mode 100644 index 00000000..49d1068a --- /dev/null +++ b/iOS/Pod/Classes/DoricViewController.m @@ -0,0 +1,71 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricViewController.h" +#import "DoricAsyncResult.h" +#import "DoricJSLoaderManager.h" +#import "DoricPanel.h" +#import "UIView+Doric.h" +#import "DoricExtensions.h" + +@implementation DoricViewController +- (instancetype)initWithScheme:(NSString *)scheme alias:(NSString *)alias { + if (self = [super init]) { + [self push:scheme alias:alias]; + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" + style:UIBarButtonItemStylePlain + target:self + action:@selector(pop)]; + } + return self; +} + +- (void)push:(NSString *)scheme alias:(NSString *)alias { + DoricAsyncResult *result = [DoricJSLoaderManager.instance request:scheme]; + result.resultCallback = ^(NSString *result) { + dispatch_async(dispatch_get_main_queue(), ^{ + DoricPanel *panel = [DoricPanel new]; + [panel.view also:^(UIView *it) { + it.backgroundColor = [UIColor whiteColor]; + it.width = self.view.width; + it.height = self.view.height - 88; + it.top = 88; + }]; + [self.view addSubview:panel.view]; + [self addChildViewController:panel]; + [panel config:result alias:alias]; + }); + }; +} + +- (void)pop { + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.childViewControllers.count > 1) { + [self.childViewControllers.lastObject also:^(UIViewController *it) { + [it removeFromParentViewController]; + [it.view removeFromSuperview]; + }]; + } else { + [self.navigationController popViewControllerAnimated:NO]; + } + + }); +} + +@end diff --git a/iOS/Pod/Classes/Engine/DoricJSCoreExecutor.h b/iOS/Pod/Classes/Engine/DoricJSCoreExecutor.h index 448f8b9e..0718eb3e 100644 --- a/iOS/Pod/Classes/Engine/DoricJSCoreExecutor.h +++ b/iOS/Pod/Classes/Engine/DoricJSCoreExecutor.h @@ -21,11 +21,11 @@ // #import -#import "DoricJSExecutorProtocal.h" +#import "DoricJSExecutorProtocol.h" NS_ASSUME_NONNULL_BEGIN -@interface DoricJSCoreExecutor : NSObject +@interface DoricJSCoreExecutor : NSObject @end diff --git a/iOS/Pod/Classes/Engine/DoricJSEngine.m b/iOS/Pod/Classes/Engine/DoricJSEngine.m index d5a9a25e..3559c0cb 100644 --- a/iOS/Pod/Classes/Engine/DoricJSEngine.m +++ b/iOS/Pod/Classes/Engine/DoricJSEngine.m @@ -21,7 +21,7 @@ // #import "DoricJSEngine.h" -#import "DoricJSExecutorProtocal.h" +#import "DoricJSExecutorProtocol.h" #import "DoricJSCoreExecutor.h" #import "DoricJSRemoteExecutor.h" #import "DoricConstant.h" @@ -29,7 +29,7 @@ #import "DoricBridgeExtension.h" @interface DoricJSEngine () -@property(nonatomic, strong) id jsExecutor; +@property(nonatomic, strong) id jsExecutor; @property(nonatomic, strong) NSMutableDictionary *timers; @property(nonatomic, strong) DoricBridgeExtension *bridgeExtension; @end diff --git a/iOS/Pod/Classes/Engine/DoricJSExecutorProtocal.h b/iOS/Pod/Classes/Engine/DoricJSExecutorProtocol.h similarity index 95% rename from iOS/Pod/Classes/Engine/DoricJSExecutorProtocal.h rename to iOS/Pod/Classes/Engine/DoricJSExecutorProtocol.h index 514a3a88..41f4bd47 100644 --- a/iOS/Pod/Classes/Engine/DoricJSExecutorProtocal.h +++ b/iOS/Pod/Classes/Engine/DoricJSExecutorProtocol.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN -@protocol DoricJSExecutorProtocal +@protocol DoricJSExecutorProtocol - (NSString *)loadJSScript:(NSString *)script source:(NSString *)source; diff --git a/iOS/Pod/Classes/Engine/DoricJSRemoteExecutor.h b/iOS/Pod/Classes/Engine/DoricJSRemoteExecutor.h index b9145867..65a34727 100644 --- a/iOS/Pod/Classes/Engine/DoricJSRemoteExecutor.h +++ b/iOS/Pod/Classes/Engine/DoricJSRemoteExecutor.h @@ -21,11 +21,11 @@ // #import -#import "DoricJSExecutorProtocal.h" +#import "DoricJSExecutorProtocol.h" NS_ASSUME_NONNULL_BEGIN -@interface DoricJSRemoteExecutor : NSObject +@interface DoricJSRemoteExecutor : NSObject @property(nonatomic, strong) dispatch_semaphore_t semaphore; diff --git a/iOS/Pod/Classes/Loader/DoricHttpJSLoader.h b/iOS/Pod/Classes/Loader/DoricHttpJSLoader.h new file mode 100644 index 00000000..ce146f58 --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricHttpJSLoader.h @@ -0,0 +1,25 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import + +#import "DoricLoaderProtocol.h" + +@interface DoricHttpJSLoader : NSObject +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Loader/DoricHttpJSLoader.m b/iOS/Pod/Classes/Loader/DoricHttpJSLoader.m new file mode 100644 index 00000000..d9bd6a2c --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricHttpJSLoader.m @@ -0,0 +1,45 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricHttpJSLoader.h" + + +@implementation DoricHttpJSLoader + +- (BOOL)filter:(NSString *)scheme { + return [scheme hasPrefix:@"http"]; +} + +- (DoricAsyncResult *)request:(NSString *)scheme { + DoricAsyncResult *ret = [DoricAsyncResult new]; + NSURL *URL = [NSURL URLWithString:scheme]; + NSURLRequest *request = [NSURLRequest requestWithURL:URL]; + [[[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] + dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (!error) { + NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [ret setupResult:dataStr]; + } else { + [ret setupError:[[NSException alloc] initWithName:@"DoricJSLoaderManager Exception" reason:error.description userInfo:nil]]; + } + }] resume]; + return ret; +} +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Loader/DoricJSLoaderManager.h b/iOS/Pod/Classes/Loader/DoricJSLoaderManager.h new file mode 100644 index 00000000..efbf2846 --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricJSLoaderManager.h @@ -0,0 +1,33 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// DoricJSLoaderManager.h +// Doric +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import +#import "DoricLoaderProtocol.h" +#import "DoricAsyncResult.h" + +@interface DoricJSLoaderManager : NSObject ++ (instancetype)instance; + +- (void)addJSLoader:(id )loader; + +- (DoricAsyncResult *)request:(NSString *)scheme; +@end diff --git a/iOS/Pod/Classes/Loader/DoricJSLoaderManager.m b/iOS/Pod/Classes/Loader/DoricJSLoaderManager.m new file mode 100644 index 00000000..41cf0fc5 --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricJSLoaderManager.m @@ -0,0 +1,68 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// DoricJSLoaderManager.m +// Doric +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricJSLoaderManager.h" +#import "DoricMainBundleJSLoader.h" +#import "DoricHttpJSLoader.h" +#import "Doric.h" + +@interface DoricJSLoaderManager () +@property(nonatomic, copy) NSSet > *loaders; +@end + +@implementation DoricJSLoaderManager ++ (instancetype)instance { + static DoricJSLoaderManager *_instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [DoricJSLoaderManager new]; + }); + return _instance; +} + +- (instancetype)init { + if (self = [super init]) { + _loaders = [[NSSet alloc] initWithArray:@[ + [DoricMainBundleJSLoader new], + [DoricHttpJSLoader new], + ]]; + } + return self; +} + +- (void)addJSLoader:(id )loader { + self.loaders = [[self.loaders mutableCopy] also:^(NSMutableSet *it) { + [it addObject:loader]; + }]; +} + +- (DoricAsyncResult *)request:(NSString *)scheme { + __block DoricAsyncResult *ret; + [self.loaders enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + if ([obj filter:scheme]) { + ret = [obj request:scheme]; + *stop = YES; + } + }]; + return ret; +} +@end diff --git a/iOS/Pod/Classes/Loader/DoricLoaderProtocol.h b/iOS/Pod/Classes/Loader/DoricLoaderProtocol.h new file mode 100644 index 00000000..b3b509f0 --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricLoaderProtocol.h @@ -0,0 +1,27 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import +#import "DoricAsyncResult.h" + +@protocol DoricLoaderProtocol +- (BOOL)filter:(NSString *)scheme; + +- (DoricAsyncResult *)request:(NSString *)scheme; +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.h b/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.h new file mode 100644 index 00000000..ff5d79ae --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.h @@ -0,0 +1,25 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import + +#import "DoricLoaderProtocol.h" + +@interface DoricMainBundleJSLoader : NSObject +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.m b/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.m new file mode 100644 index 00000000..63663098 --- /dev/null +++ b/iOS/Pod/Classes/Loader/DoricMainBundleJSLoader.m @@ -0,0 +1,42 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricMainBundleJSLoader.h" + + +@implementation DoricMainBundleJSLoader +- (BOOL)filter:(NSString *)scheme { + return [scheme hasPrefix:@"assets"]; +} + +- (DoricAsyncResult *)request:(NSString *)scheme { + DoricAsyncResult *ret = [DoricAsyncResult new]; + NSString *path = [[NSBundle mainBundle] bundlePath]; + NSString *fullPath = [path stringByAppendingPathComponent:[scheme substringFromIndex:@"assets://".length]]; + NSError *error; + NSString *jsContent = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:&error]; + if (error) { + [ret setupError:[NSException new]]; + } else { + [ret setupResult:jsContent]; + } + return ret; +} + +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Navigator/DoricNavigatorProtocol.h b/iOS/Pod/Classes/Navigator/DoricNavigatorProtocol.h new file mode 100644 index 00000000..dd250290 --- /dev/null +++ b/iOS/Pod/Classes/Navigator/DoricNavigatorProtocol.h @@ -0,0 +1,11 @@ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import + +@protocol DoricNavigatorProtocol +- (void)push:(NSString *)scheme alias:(NSString *)alias; + +- (void)pop; +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.h b/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.h new file mode 100644 index 00000000..d5ea4947 --- /dev/null +++ b/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.h @@ -0,0 +1,24 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import +#import "DoricNativePlugin.h" + +@interface DoricNavigatorPlugin : DoricNativePlugin +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m b/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m new file mode 100644 index 00000000..d711b304 --- /dev/null +++ b/iOS/Pod/Classes/Plugin/DoricNavigatorPlugin.m @@ -0,0 +1,31 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Created by pengfei.zhou on 2019/11/23. +// + +#import "DoricNavigatorPlugin.h" + + +@implementation DoricNavigatorPlugin +- (void)push:(NSDictionary *)params { + [self.doricContext.navigator push:params[@"scheme"] alias:params[@"alias"]]; +} + +- (void)pop { + [self.doricContext.navigator pop]; +} +@end \ No newline at end of file diff --git a/iOS/Pod/Classes/Util/DoricAsyncResult.h b/iOS/Pod/Classes/Util/DoricAsyncResult.h index 9eb813ff..6a5b6a7d 100644 --- a/iOS/Pod/Classes/Util/DoricAsyncResult.h +++ b/iOS/Pod/Classes/Util/DoricAsyncResult.h @@ -26,15 +26,9 @@ NS_ASSUME_NONNULL_BEGIN @interface DoricAsyncResult : NSObject -typedef void(^DoricResultCallback)(R); - -typedef void(^DoricExceptionCallback)(NSException *); - -typedef void(^DoricFinishCallback)(void); - -@property(nonatomic, strong) DoricResultCallback resultCallback; -@property(nonatomic, strong) DoricExceptionCallback exceptionCallback; -@property(nonatomic, strong) DoricFinishCallback finishCallback; +@property(nonatomic, strong) void (^resultCallback)(R result); +@property(nonatomic, strong) void (^exceptionCallback)(NSException *e); +@property(nonatomic, strong) void (^finishCallback)(void); - (void)setupResult:(R)result; diff --git a/iOS/Pod/Classes/Util/DoricAsyncResult.m b/iOS/Pod/Classes/Util/DoricAsyncResult.m index 786f2eff..e70b8805 100644 --- a/iOS/Pod/Classes/Util/DoricAsyncResult.m +++ b/iOS/Pod/Classes/Util/DoricAsyncResult.m @@ -56,24 +56,24 @@ - (id)getResult { return self.result; } -- (void)setResultCallback:(DoricResultCallback)callback { +- (void)setResultCallback:(void (^)(id))callback { _resultCallback = callback; if (self.result && ![self.result isKindOfClass:[NSException class]]) { callback(self.result); } } -- (void)setExceptionCallback:(DoricExceptionCallback)exceptionCallback { +- (void)setExceptionCallback:(void (^)(NSException *))exceptionCallback { _exceptionCallback = exceptionCallback; if ([self.result isKindOfClass:[NSException class]]) { exceptionCallback(self.result); } } -- (void)setFinishCallback:(DoricFinishCallback)callback { - _finishCallback = callback; +- (void)setFinishCallback:(void (^)(void))finishCallback { + _finishCallback = finishCallback; if (self.result) { - callback(); + finishCallback(); } } diff --git a/js-framework/src/ui/panel.ts b/js-framework/src/ui/panel.ts index 6d708f54..abc84bda 100644 --- a/js-framework/src/ui/panel.ts +++ b/js-framework/src/ui/panel.ts @@ -56,6 +56,7 @@ export abstract class Panel { this.__data__ = data this.__root__.width = frame.width this.__root__.height = frame.height + this.__root__.children.length = 0 this.build(this.__root__) } diff --git a/js-framework/src/util/nativeModules.ts b/js-framework/src/util/nativeModules.ts index 9673b4e7..d46ced99 100644 --- a/js-framework/src/util/nativeModules.ts +++ b/js-framework/src/util/nativeModules.ts @@ -166,4 +166,17 @@ export function storage(context: BridgeContext) { return context.storage.clear({ zone }) }, } +} + +export function navigator(context: BridgeContext) { + return { + push: (scheme: string, alias: string) => { + return context.navigator.push({ + scheme, alias + }) + }, + pop: () => { + return context.navigator.pop() + }, + } } \ No newline at end of file