Can a react-native application fetch for remote html/js/css/img files, save to local and load in a WebView?
Context:
Take as an example the following app structure:
├── App.js
├── /remote-assets
│ └── /foo
│ ├── index.html
│ ├── app.js
│ ├── styles.js
│ └── logo.jpg
└── /local-assets
├── util.js
└── background.jpg
The idea is that the App.js fetches assets into the directoy remote-assets and later loads the index.html into a WebView. That html will also reference files that are in the same local path, like:
<script src="app.js"></script>
<img src="logo.jpg" />
And also assets that are local, for example:
<script src="../../local-assets/util.js"></script>
<img src="../../local-assets/background.jpg" />
Related
I am building an static markdown blog website using Vue3,and I am using require.context() to load markdown files.
This is the project structure,and I load files from static/posts.
├── dist
│ ├── assets
│ │ └── static
│ │ └── posts
│ │ ├── dev-first-vue3-todolist.md
│ │ ├── dev-fix-missing-xcrun.md
├── package.json
├── src
│ ├── App.vue
│ ├── main.js
├── static
│ └── posts
│ ├── dev-first-vue3-todolist.md
│ ├── dev-fix-missing-xcrun.md
└── vue.config.js
Here's how I load these markdown files.
let context = require.context("../static/posts", true, /\.md$/, "sync");
let keys = context.keys();
// the markdown file list
const postRawList = [];
keys.forEach((key) => {
const raw = context(key).default;
postRawList.push(raw);
});
It worked well. I can read postRawList from static/posts and render them by markdown parser.
The point is, I want my blog website static, so when I build this Vue app I use copy-webpack-plugin to copy these markdown files from static/posts to dist/assets/static/posts and it worked well.
config.plugins.push(
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, "static/posts"),
to: path.resolve(__dirname, "dist/assets/static/posts"),
},
],
})
);
I want to manage my markdown posts only by adding or deleting markdown files in dist/assets/static/posts.
But after I changing the markdown files in dist/assets/static/posts(like delete dev-first-vue3-todolist.md) ,the markdown object list(postRawList) doesn't be updated.
The markdown list is the same as the markdown list in static/posts , and no matter how I change files in this 2 posts folder,it does't be updated.
I guess it is caused by "require cache", and I had tried to delete cache after changing the files, but it did't work.
delete require.cache[context.id];
So I want to know why the file objects not be updated after I built the app and change the files in markdown directory(loaded by require.context()).
This is my first time asking questions on stackoverflow,and I feel sorry if I didn't make it clear.
I have a legend inside the map, is working fine when the map is not full screen, but when the map is full screen the legend is not showing.
To Reproduce
Steps to reproduce the behavior:
Open the map and see the legend is present and working fine
Click full screen icon
The legend is not present
Click full screen icon again to remove the full screen, now the legend is present and working fine
Expected behavior
The legend should work fine when full screen.
Screenshots
Normal screen, working fine:
Full screen, not showing the legend:
Additional context
Code example available on codesandbox https://codesandbox.io/s/ecstatic-wave-c3qmg. You should open the link https://c3qmg.csb.app/ on another page to be able to see the fullscreen icon.
Code extract:
<template>
<!-- MapBox map -->
<MglMap
ref="customMap"
:mapStyle="map.mapStyle"
:zoom="map.zoom"
:center="map.center"
:attributionControl="false"
#mousemove="mouseMoved"
#click="mapClick"
>
<MglFullscreenControl position="top-left" />
<MglNavigationControl position="top-left" />
<MglScaleControl position="bottom-left" />
<!-- Custom html legend, using the feature selected-->
<MapLegend :feature="selectedFeature" />
<div
v-for="geoJsonLayer in getGeoJsonLayers.mapLayers"
:key="geoJsonLayer.id"
>
<!-- Fill geojson -->
<MglGeojsonLayer
:sourceId="geoJsonLayer.sourceId"
:source="geoJsonLayer.source"
:layerId="geoJsonLayer.layerId"
:layer="geoJsonLayer.layer"
/>
<!-- Source is not needed but the source id is needed :) when you are using an already defined source above -->
<!-- Outline geojson -->
<MglGeojsonLayer
:sourceId="`${geoJsonLayer.outlineLayerId}-source`"
:layerId="geoJsonLayer.outlineLayerId"
:layer="geoJsonLayer.outlineLayer"
/>
</div>
</MglMap>
</template>
Node packages installed:
├── #highcharts/map-collection#1.1.3
├── #vue/cli-plugin-babel#4.2.3
├── #vue/cli-plugin-eslint#4.2.3
├── #vue/cli-service#4.2.3
├── axios#0.19.2
├── babel-eslint#10.1.0
├── bootstrap-vue#2.21.2
├── bootstrap#4.6.0
├── core-js#3.9.1
├── d3-drag#2.0.0
├── d3-force#2.1.1
├── d3#6.6.1
├── eslint-plugin-vue#6.2.2
├── eslint#6.8.0
├── highcharts-vue#1.3.5
├── highcharts#8.2.2
├── leaflet.heat#0.2.0
├── leaflet#1.7.1
├── mapbox-gl#0.53.1
├── moment-timezone#0.5.33
├── proj4#2.7.2
├── qs#6.10.1
├── vue-axios#2.1.5
├── vue-i18n#8.24.2
├── vue-mapbox#0.4.1
├── vue-router#3.5.1
├── vue-template-compiler#2.6.12
├── vue#2.6.12
└── vuex#3.6.2
By default, the Mapbox GL JS fullscreen control only makes the map container itself full screen. Nothing else on the screen will be visible.
So you need to pass the container element through to Vue-Mapbox's MglFullScreenControl as the container parameter, along these lines:
<div id="mycontainer">
<MglMap
:accessToken="accessToken"
:mapStyle="mapStyle"
:zoom="zoom"
:center="center"
ref="map"
class="default-map-xl"
>
<MglFullscreenControl position="top-left" :container="containerElement"/>
<MapBoxLegend :selectedFeature="selectedFeature" />
</MglMap>
There's probably a better way to do this, but you can set that element as a data property once your component mounts.
data() {
return {
//...
containerElement: null
};
},
mounted() {
this.containerElement = document.getElementById('mycontainer')
}
I forked your code sandbox here.
recently I've been working on a chrome extension that uses vue as the frontend. The vue boilerplate that enables the extension to run on the browser uses webpack and is downloaded with:
vue init kocal/vue-web-extension name
and gives this project structure :
.
├── dist
│ └── <the built extension>
├── node_modules
│ └── <one or two files and folders>
├── package.json
├── package-lock.json
├── scripts
│ ├── build-zip.js
│ └── remove-evals.js
├── src
│ ├── background.js
│ ├── icons
│ │ ├── icon_128.png
│ │ ├── icon_48.png
│ │ └── icon.xcf
│ ├── manifest.json
│ └── popup
│ ├── App.vue
│ ├── popup.html
│ └── popup.js
└── webpack.config.js
The problem with this setup is that now I'm trying to implement OCR using tesseract.js and because chrome extensions don't let you use CDNs or outside libraries I need to download tesseract.js files locally. I looked through this link about downloading locally and also referenced tesseract.js' example on using tesseract.js with chrome extension (https://github.com/jeromewu/tesseract.js-chrome-extension), however when I'm loading the library I keep encountering the problem
tesseract.min.js:688 Uncaught Error: ReferenceError: window is not defined
at eval (tesseract.min.js:688)
at Worker.e.onmessage (tesseract.min.js:1579)
The current tesseract code I have right now in a vue file is (App.vue) and the problem seems to happen on await worker.load():
const { createWorker } = Tesseract;
const worker = createWorker({
workerPath: chrome.runtime.getURL("js/worker.min.js"),
langPath: chrome.runtime.getURL("traineddata"),
corePath: chrome.runtime.getURL("js/tesseract-core.wasm.js")
});
async function extract() {
console.log("test1");
await worker.load();
console.log("test2");
await worker.loadLanguage("eng");
await worker.initialize("eng");
const {
data: { text }
} = await worker.recognize("https://tesseract.projectnaptha.com/img/eng_bw.png");
console.log(text);
await worker.terminate();
}
extract();
Html page includes (tab.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="tab.css" />
<script src="../js/tesseract.min.js"></script>
</head>
<body>
<div id="app"></div>
<script src="tab.js"></script>
</body>
</html>
and js file (tab.js):
import Vue from "vue";
import App from "./App";
/* eslint-disable no-new */
new Vue({
el: "#app",
render: h => h(App)
});
My current file structure looks like this:
File structure
I've been stuck on this problem for quite a while now so any help would be greatly appreciated!
Although I can't help you with your question per se (and it's been over six months without anyone else answering), I thought I'd let you know how I solved my similar problem.
I too wanted an OCR function in a chrome extension and started digging into tesseract to begin with. When I couldn't solve it I moved on and instead used OCRAD.js and GOCR.js for my project. Although perhaps not quite as powerful as tesseract, I'm fully satisfied with my result.
Both OCRAD and GOCR are simple to include in your manifest.json and then you call the functions in your script by calling them as functions: OCRAD(image) or GOCR(image).
OCRAD has a nice demo page where you can test the functionality for your desired images before using it: https://antimatter15.com/ocrad.js/demo.html
I would like to extend my controller within simple widget.
I've created two files:
app/widgets/mywidget/controllers/base.js
app/widgets/mywidget/controllers/index.js
I start mycontroller.js file with line: exports.baseController = 'base'; and on Android it crashes with Exception:
/V8Exception(19693): Exception occurred at ti:/module.js:280: Uncaught Error: Requested module not found: alloy/controllers//glass/parent
Project tree looks like this:
app
├── README
├── alloy.js
├── assets
├── config.json
├── controllers
│ ├── base.js
│ ├── index.js
│ └── view.js
├── lib
│ └── user.js
├── models
├── styles
│ ├── app.tss
│ └── index.tss
├── views
│ ├── index.xml
│ └── view.xml
└── widgets
└── mywidget
├── controllers
│ ├── base.js
│ ├── index.js
│ └── view.js
├── styles
├── views
└── widget.json
index.js & view.js inside app/controller use base.js as baseController.
index.js & view.js inside app/widgets/mywidget/controllers use base.js inside same directory as their baseController. I don't try to extend baseController from app inside widget.
I'm busy creating an Admin module and extending the ModuleAdminController class. I'm trying to add some CSS by using the following:
class AdminPrintspecJobsController extends ModuleAdminController
{
public function setMedia()
{
parent::setMedia();
$this->addCss(_MODULE_DIR_ . $this->module->name . "/css/printspec_table.css");
}
// ...
}
When I refresh my admin page, in Chrome, the Network panel indicates the file is added to the DOM, but it fails with an HTTP 404, not found error.
My folder structure looks as follows:
.
├── AdminTab.gif
├── config.xml
├── controllers
│ └── admin
│ ├── AdminPrintspecJobs.php
│ └── AdminTab.php
├── css
│ └── printspec_table.css
├── printspec.php
└── views
└── templates
└── admin
└── printspec_jobs
└── jobs.tpl
What am I doing wrong here?
I've managed to get it working by turning Friendly URLs off and then on again.