diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 3d8be98f..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,28 +0,0 @@ -# CODEOWNERS documentation : https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners - -# ============== -# Platform stuff -# ============== -# !!! Always keep it on the last lines of the CODEOWNERS file !!! - -# Deployfile gives rights to modify productions resources -/Deployfile @ContentSquare/Platform - -# Jenkinsfile has access to secrets and grants access to AWS resources -/Jenkinsfile @ContentSquare/Platform - -# Makefile are called by Jenkinsfile and inherit their access -Makefile* @ContentSquare/Platform - -# Dockerfile describes the images that will be put into production -Dockerfile* @ContentSquare/Platform - -# .github controls CODEOWNERS and Github actions (not used at the moment) -/.github/ @ContentSquare/Platform - -# .infra describes the production resources -.infra/ @ContentSquare/Platform - -# ============== -# Platform stuff -# ============== diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 00000000..362291eb --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,28 @@ +name: readapt ci + +on: + pull_request: + branches: [ "master", "release/ms-word-addin"] + push: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16.x + - run: npm i -g --force yarn + - run: yarn install --frozen-lockfile + - run: yarn audit --groups dependencies + - run: yarn lint + - run: yarn build-deps + - run: yarn test --ci + - run: yarn workspace chrome-extension build + - run: yarn workspace ms-word-addin build + + + diff --git a/.gitignore b/.gitignore index ed4ea5da..188e5e37 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ coverage/ .idea dist/ .vscode/lauch.js +.env* +!.env-template .parcel-cache *.tsbuildinfo diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..0cdfd923 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,10 @@ +# Contributor Code of Conduct + +As contributors and maintainers of the Readapt project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities. +Communication through any of Readapt’s channels (GitHub, YouTube, email etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. + +We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, visible or invisible disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Readapt project to do the same. + +If any member of the community violates this code of conduct, the maintainers of the Readapt project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate. + +If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at readapt@contentsquare.com. diff --git a/Makefile b/Makefile deleted file mode 100644 index 886b109b..00000000 --- a/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# This file will be reviewed by Platform team because it is called by the Jenkinsfile with additional AWS rights and/or access to secrets -# You can modify it but a platformer approval will be required before merging it diff --git a/README.md b/README.md index e3a878de..39d44e71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Readapt +[![readapt ci](https://github.com/ContentSquare/readapt/actions/workflows/main.yaml/badge.svg)](https://github.com/ContentSquare/readapt/actions/workflows/main.yaml) + ## Introduction Created by [Contentsquare Foundation](https://contentsquare-foundation.org/), Readapt is a software platform that aims @@ -99,4 +101,4 @@ To clean all packages and return to a fresh state run `yarn workspaces clean`. ## License -[Apache License, Version 2.0](https://choosealicense.com/licenses/apache-2.0/) +All code and dictionaries are published under [Apache License, Version 2.0](https://choosealicense.com/licenses/apache-2.0/), except for the French dictionary which is published under [Creative Commons BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). diff --git a/apps/chrome-extension/.env-template b/apps/chrome-extension/.env-template new file mode 100644 index 00000000..debd5d65 --- /dev/null +++ b/apps/chrome-extension/.env-template @@ -0,0 +1 @@ +MATOMO_URL= diff --git a/apps/chrome-extension/README.md b/apps/chrome-extension/README.md index 2ebe4028..586e15c8 100644 --- a/apps/chrome-extension/README.md +++ b/apps/chrome-extension/README.md @@ -2,9 +2,9 @@ ## Introduction -Created by [Contentsquare Foundation](https://contentsquare-foundation.org/), Readapt is a software platform that aims to help those with reading challenges like dyslexia to more easily read digital text. The [Chrome extension](https://chrome.google.com/webstore/detail/readapt/emgfmfgandmhbgleikkoaebngboghfpe) version of Readapt allows users to set their reading preferences and adapt text on websites. It also provides reading tools like a screen mask and reading ruler. +Created by [Contentsquare Foundation](https://contentsquare-foundation.org/), Readapt is a software platform that aims to help those with reading challenges like dyslexia to more easily read digital text. The [Chrome extension](https://chrome.google.com/webstore/detail/readapt/emgfmfgandmhbgleikkoaebngboghfpe) version of Readapt allows users to set their reading preferences and adapt text on websites. It also provides reading tools like a screen mask and reading ruler. -This Chrome extension is compatible with many Chromium-based browsers like Google Chrome and Microsoft Edge (web view 2). It is available in English and French. +This Chrome extension is compatible with many Chromium-based browsers like Google Chrome and Microsoft Edge (web view 2). It is available in English and French. ## How the Readapt Chrome extension works After installing the extension, you can click on the extension to either create your profile from scratch or select from one of our reading templates. After saving your preferences, you can start to adapt text on websites by holding the control (Windows) or command ⌘ key (Mac) and left-clicking on your target text. To remove the text adaptation, you can either click on the extension and click on "Reset text on page", or right-click on the webpage and select "Readapt > Reset all text". @@ -17,6 +17,10 @@ The reading tools (screen mask and reading ruler) can be activated on a webpage yarn install ``` +### Setup env var + +After install an `.env` file will be generated, please fill missing values + ### Compiles and hot-reloads for development ``` yarn serve diff --git a/apps/chrome-extension/manifest.json b/apps/chrome-extension/manifest.json index 38d74d1f..259e914d 100644 --- a/apps/chrome-extension/manifest.json +++ b/apps/chrome-extension/manifest.json @@ -1,6 +1,6 @@ { "name": "Readapt", - "description": "Readapt by Contentsquare", + "description": "Readapt by Contentsquare Foundation", "version": "0.0.0", "manifest_version": 3, "action": { diff --git a/apps/chrome-extension/package.json b/apps/chrome-extension/package.json index 935f39f5..fb36a4da 100644 --- a/apps/chrome-extension/package.json +++ b/apps/chrome-extension/package.json @@ -1,30 +1,34 @@ { "name": "chrome-extension", - "version": "1.0.0", + "version": "1.2.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build && yarn build-extension", "build-extension": "rollup -c src-extension/rollup.config.js", "clean": "shx rm -rf dist", + "test": "yarn test:unit", "test:unit": "vue-cli-service test:unit", "lint": "vue-cli-service lint", - "package": "scripts/package-release" + "package": "scripts/package-release", + "postinstall": "node scripts/init-env" }, "dependencies": { - "@readapt/settings": "^1.0.0", - "@readapt/shared-components": "^1.0.0", - "@readapt/text-engine": "^1.0.0", - "@readapt/visual-engine": "^1.0.0", + "@readapt/settings": "^1.2.0", + "@readapt/shared-components": "^1.2.0", + "@readapt/text-engine": "^1.2.0", + "@readapt/visual-engine": "^1.2.0", "@vue/composition-api": "~1.4.5", "bootstrap": "~4.6.1", "bootstrap-vue": "~2.22.0", "core-js": "^3.8.3", + "dotenv": "^16.0.1", "lodash": "^4.17.21", "popper.js": "^1.16.1", "vue": "~2.6.14", "vue-i18n": "~8.27.0", "vue-router": "~3.5.1", + "vue-sanitize": "^0.2.2", "vuex": "~3.6.2" }, "devDependencies": { diff --git a/apps/chrome-extension/scripts/init-env b/apps/chrome-extension/scripts/init-env new file mode 100755 index 00000000..0987ccfd --- /dev/null +++ b/apps/chrome-extension/scripts/init-env @@ -0,0 +1,17 @@ +#!/usr/bin/env node +/* + This script check env file or create it from template with default values. +*/ +const fs = require('fs'); +const path = require('path') + +const ENV_FILE_PATH = path.join(__dirname, '../.env'); + + +if (!fs.existsSync(ENV_FILE_PATH)) { + const ENV_TEMPLATE_PATH = path.join(__dirname, '../.env-template'); + fs.copyFileSync(ENV_TEMPLATE_PATH, ENV_FILE_PATH) + console.log('.env file created with default values, please setup missing values') +} else { + console.log('Check .env file OK') +} diff --git a/apps/chrome-extension/src-extension/background.ts b/apps/chrome-extension/src-extension/background.ts index 85a1c999..66c0a004 100644 --- a/apps/chrome-extension/src-extension/background.ts +++ b/apps/chrome-extension/src-extension/background.ts @@ -93,6 +93,11 @@ chrome.storage.onChanged.addListener(async (changes) => { if (hasSettingsChanged(changes)) { await broadcastMessage('REFRESH') } + + const matomoURL = '__MATOMO_URL' + if (matomoURL && hasEventChanged(changes)) { + await fetch(`${matomoURL}/matomo.php?idsite=1&action_name=adapt&rec=1`) + } }) const hasEnabledChanged = (changes: { [p: string]: chrome.storage.StorageChange }): boolean => { @@ -104,6 +109,15 @@ const hasEnabledChanged = (changes: { [p: string]: chrome.storage.StorageChange return false } +const hasEventChanged = (changes: { [p: string]: chrome.storage.StorageChange }): boolean => { + for (const [key] of Object.entries(changes)) { + if (key === 'event') { + return true + } + } + return false +} + const switchEnabledContextMenu = (enabled: boolean): void => { // chrome.contextMenus.update('readaptMenuAdaptAction', { visible: enabled }) chrome.contextMenus.update('readaptMenuResetAction', { visible: enabled }) diff --git a/apps/chrome-extension/src-extension/readapt.ts b/apps/chrome-extension/src-extension/readapt.ts index 80092490..4ac537ef 100644 --- a/apps/chrome-extension/src-extension/readapt.ts +++ b/apps/chrome-extension/src-extension/readapt.ts @@ -196,6 +196,7 @@ const adaptHtmlElement = async (element: HTMLElement): Promise => { console.error('Something went wrong when adapting element', element) console.error(error) } + chrome.storage.local.set({ event: `adapt:${new Date().toISOString()}` }).catch(console.error) document.body.classList.remove('readapt-loading') } diff --git a/apps/chrome-extension/src-extension/rollup.config.js b/apps/chrome-extension/src-extension/rollup.config.js index 9a8eea33..08ec6c4e 100644 --- a/apps/chrome-extension/src-extension/rollup.config.js +++ b/apps/chrome-extension/src-extension/rollup.config.js @@ -3,12 +3,14 @@ import resolve from '@rollup/plugin-node-resolve' import commonjs from '@rollup/plugin-commonjs' import { terser } from 'rollup-plugin-terser' import path from 'path' +import replace from '@rollup/plugin-replace' +require('dotenv').config() export default [ { input: path.join(__dirname, './background.ts'), output: [{ file: './dist/scripts/background.js', format: 'iife' }], - plugins: [ts(), resolve(), commonjs(), terser({ compress: true })] + plugins: [replace({ __MATOMO_URL: process.env.MATOMO_URL }), ts(), resolve(), commonjs(), terser({ compress: true })] }, { input: path.join(__dirname, './readapt.ts'), diff --git a/apps/chrome-extension/src/components/AdaptContainer.vue b/apps/chrome-extension/src/components/AdaptContainer.vue index 39cf0918..99d172a5 100644 --- a/apps/chrome-extension/src/components/AdaptContainer.vue +++ b/apps/chrome-extension/src/components/AdaptContainer.vue @@ -2,40 +2,62 @@ import { adaptHtmlElementAsync } from '@/visualEngine/adaptHtmlElementAsync' import { removeStyleElement } from '@readapt/visual-engine' import { Settings } from '@readapt/settings' -import { defineComponent, PropType, ref, watch, watchEffect, onUnmounted } from '@vue/composition-api' +import { defineComponent, PropType, ref, onUnmounted, watch } from '@vue/composition-api' +import { BSpinner } from 'bootstrap-vue' const AdaptContainer = defineComponent({ + components: { BSpinner }, props: { contentToAdapt: { type: String, required: true }, settings: { type: Object as PropType, required: true }, scope: { type: String, default: 'preview' } }, - setup(props, { emit }) { - const containerElement = ref() + setup(props) { + const isLoading = ref(true) + const containerElement = ref() - const ready = ref(false) + const adaptContent = async () => { + if (containerElement.value && props.contentToAdapt) { + containerElement.value.innerHTML = props.contentToAdapt + await adaptHtmlElementAsync(containerElement.value, props.settings, props.scope) + isLoading.value = false + } + } - onUnmounted(() => removeStyleElement(props.scope)) - - watch(ready, (isReadyNow) => isReadyNow && emit('ready')) - - watchEffect( - async () => { - if (containerElement.value && props.contentToAdapt) { - containerElement.value.innerHTML = props.contentToAdapt - await adaptHtmlElementAsync(containerElement.value, props.settings, props.scope) - // ready after first adaptation - ready.value = true - } - }, - { flush: 'post' } + watch( + () => ({ + ...props, + containerElement: containerElement.value + }), + () => adaptContent(), + { deep: true, flush: 'post' } ) - return { containerElement } + onUnmounted(() => removeStyleElement(props.scope)) + + return { isLoading, containerElement } } }) export default AdaptContainer + + diff --git a/apps/chrome-extension/src/components/PreviewContainer.vue b/apps/chrome-extension/src/components/PreviewContainer.vue new file mode 100644 index 00000000..e075b599 --- /dev/null +++ b/apps/chrome-extension/src/components/PreviewContainer.vue @@ -0,0 +1,62 @@ + +