Skip to content

Commit

Permalink
No document deps (#2359)
Browse files Browse the repository at this point in the history
  • Loading branch information
corrideat authored Sep 20, 2024
1 parent c5c4e3c commit 9fd5e16
Show file tree
Hide file tree
Showing 24 changed files with 106 additions and 98 deletions.
2 changes: 0 additions & 2 deletions frontend/common/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
// Doing otherwise defeats the purpose of this file and could lead to bugs and conflicts!
// You may *add* behavior, but never modify or remove it.

export { default as Vue } from 'vue'
export { default as L } from './translations.js'
export * from './translations.js'
export * from './errors.js'
export * as Errors from './errors.js'
77 changes: 8 additions & 69 deletions frontend/common/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,12 @@

// since this file is loaded by common.js, we avoid circular imports and directly import
import sbp from '@sbp/sbp'
import Vue from 'vue'
import dompurify from 'dompurify'
import { defaultConfig as defaultDompurifyConfig } from './vSafeHtml.js'
import template from './stringTemplate.js'

Vue.prototype.L = L
Vue.prototype.LTags = LTags

const defaultLanguage = 'en-US'
const defaultLanguageCode = 'en'
const defaultTranslationTable: { [string]: string } = {}

/**
* Allow 'href' and 'target' attributes to avoid breaking our hyperlinks,
* but keep sanitizing their values.
* See https://github.com/cure53/DOMPurify#can-i-configure-dompurify
*/
const dompurifyConfig = {
...defaultDompurifyConfig,
ALLOWED_ATTR: ['class', 'href', 'rel', 'target'],
ALLOWED_TAGS: ['a', 'b', 'br', 'button', 'em', 'i', 'p', 'small', 'span', 'strong', 'sub', 'sup', 'u'],
RETURN_DOM_FRAGMENT: false
}

let currentLanguage = defaultLanguage
let currentLanguageCode = defaultLanguage.split('-')[0]
let currentTranslationTable = defaultTranslationTable
Expand All @@ -40,7 +22,7 @@ let currentTranslationTable = defaultTranslationTable
*
* @see https://tools.ietf.org/rfc/bcp/bcp47.txt
*/
sbp('sbp/selectors/register', {
export default (sbp('sbp/selectors/register', {
'translations/init': async function init (language: string): Promise<void> {
// A language code is usually the first part of a language tag.
const [languageCode] = language.toLowerCase().split('-')
Expand Down Expand Up @@ -69,7 +51,7 @@ sbp('sbp/selectors/register', {
console.error(error)
}
}
})
}): string[])

/*
Examples:
Expand Down Expand Up @@ -122,19 +104,22 @@ export function LTags (...tags: string[]): {|br_: string|} {
return o
}

export default function L (
export function L (
key: string,
args: Array<*> | Object | void
): string {
return template(currentTranslationTable[key] || key, args)
// Avoid inopportune linebreaks before certain punctuations.
.replace(/\s(?=[;:?!])/g, '&nbsp;')
// '\u00a0' is a non-breaking space
// The character is used instead of `&nbsp;` or `&#160;` for conciseness
// and compatibility.
.replace(/\s(?=[;:?!])/g, '\u00a0')
}

export function LError (error: Error, toGithub?: boolean): {|reportError: any|} {
let url = 'https://github.com/okTurtles/group-income/issues'
if (!toGithub && sbp('state/vuex/state').loggedIn) {
const baseRoute = document.location.origin + sbp('controller/router').options.base
const baseRoute = sbp('controller/router').options.base
url = `${baseRoute}?modal=UserSettingsModal&tab=application-logs&errorMsg=${encodeURIComponent(error.message)}`
}
return {
Expand All @@ -145,49 +130,3 @@ export function LError (error: Error, toGithub?: boolean): {|reportError: any|}
})
}
}

function sanitize (inputString) {
return dompurify.sanitize(inputString, dompurifyConfig)
}

Vue.component('i18n', {
functional: true,
props: {
args: [Object, Array],
tag: {
type: String,
default: 'span'
},
compile: Boolean
},
render: function (h, context) {
const text = context.children[0].text
const translation = L(text, context.props.args || {})
if (!translation) {
console.warn('The following i18n text was not translated correctly:', text)
return h(context.props.tag, context.data, text)
}
// Prevent reverse tabnabbing by including `rel="noopener noreferrer"` when rendering as an outbound hyperlink.
if (context.props.tag === 'a' && context.data.attrs.target === '_blank') {
context.data.attrs.rel = 'noopener noreferrer'
}
if (context.props.compile) {
const result = Vue.compile('<wrap>' + sanitize(translation) + '</wrap>')
// console.log('TRANSLATED RENDERED TEXT:', context, result.render.toString())
return result.render.call({
_c: (tag, ...args) => {
if (tag === 'wrap') {
return h(context.props.tag, context.data, ...args)
} else {
return h(tag, ...args)
}
},
_v: x => x
})
} else {
if (!context.data.domProps) context.data.domProps = {}
context.data.domProps.innerHTML = sanitize(translation)
return h(context.props.tag, context.data)
}
}
})
4 changes: 1 addition & 3 deletions frontend/controller/app/identity.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
'use strict'

import * as Common from '@common/common.js'
import { GIErrorUIRuntimeError, L, LError, LTags } from '@common/common.js'
import { cloneDeep } from '@model/contracts/shared/giLodash.js'
import sbp from '@sbp/sbp'
import Vue from 'vue'
import { LOGIN, LOGIN_COMPLETE, LOGIN_ERROR } from '~/frontend/utils/events.js'
import { Secret } from '~/shared/domains/chelonia/Secret.js'
import { boxKeyPair, buildRegisterSaltRequest, computeCAndHc, decryptContractSalt, hash, hashPassword, randomNonce } from '~/shared/zkpp.js'
// Using relative path to crypto.js instead of ~-path to workaround some esbuild bug
import { CURVE25519XSALSA20POLY1305, EDWARDS25519SHA512BATCH, deriveKeyFromPassword, serializeKey } from '../../../shared/domains/chelonia/crypto.js'
import { handleFetchResult } from '../utils/misc.js'

const { Vue } = Common

const loadState = async (identityContractID: string, password: ?string) => {
if (password) {
const stateKeyEncryptionKeyFn = (stateEncryptionKeyId, salt) => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/controller/router.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict'

import sbp from '@sbp/sbp'
import { Vue, L } from '@common/common.js'
import { L } from '@common/common.js'
import Router from 'vue-router'
import store from '~/frontend/model/state.js'
import Home from '@pages/Home.vue'
import Join from '@pages/Join.vue'
import { lazyPage } from '@utils/lazyLoadedView.js'
import Vue from 'vue'

/*
* Lazy load all the pages that are not necessary at initial loading of the app.
Expand Down
6 changes: 3 additions & 3 deletions frontend/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

// import SBP stuff before anything else so that domains register themselves before called
import * as Common from '@common/common.js'
import { L, LError } from '@common/common.js'
import '@model/captureLogs.js'
import '@sbp/okturtles.data'
import '@sbp/okturtles.eventqueue'
Expand Down Expand Up @@ -31,10 +31,12 @@ import Modal from './views/components/modal/Modal.vue'
import BackgroundSounds from './views/components/sounds/Background.vue'
import Navigation from './views/containers/navigation/Navigation.vue'
import './views/utils/avatar.js'
import './views/utils/i18n.js'
import './views/utils/ui.js'
import './views/utils/vError.js'
import './views/utils/vFocus.js'
// import './views/utils/vSafeHtml.js' // this gets imported by translations, which is part of common.js
import Vue from 'vue'
import notificationsMixin from './model/notifications/mainNotificationsMixin.js'
import './model/notifications/periodicNotifications.js'
import setupChelonia from './setupChelonia.js'
Expand All @@ -43,8 +45,6 @@ import './utils/touchInteractions.js'
import { showNavMixin } from './views/utils/misc.js'
import './views/utils/vStyle.js'

const { Vue, L, LError } = Common

console.info('GI_VERSION:', process.env.GI_VERSION)
console.info('CONTRACTS_VERSION:', process.env.CONTRACTS_VERSION)
console.info('LIGHTWEIGHT_CLIENT:', process.env.LIGHTWEIGHT_CLIENT)
Expand Down
3 changes: 2 additions & 1 deletion frontend/model/chatroom/vuexModule.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict'

import sbp from '@sbp/sbp'
import { Vue } from '@common/common.js'
import { merge, cloneDeep, union } from '@model/contracts/shared/giLodash.js'
import { MESSAGE_NOTIFY_SETTINGS, CHATROOM_PRIVACY_LEVEL } from '@model/contracts/shared/constants.js'
import Vue from 'vue'

const defaultState = {
currentChatRoomIDs: {}, // { [groupId]: currentChatRoomId }
pendingChatRoomIDs: {}, // { [groupId]: currentChatRoomId }
Expand Down
3 changes: 1 addition & 2 deletions frontend/model/contracts/shared/voting/proposals.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

import sbp from '@sbp/sbp'
import { Vue } from '@common/common.js'
import { objectOf, literalOf, unionOf, number } from '~/frontend/model/contracts/misc/flowTyper.js'
import { DAYS_MILLIS } from '../time.js'
import rules, { ruleType, VOTE_AGAINST, VOTE_FOR, RULE_PERCENTAGE, RULE_DISAGREEMENT } from './rules.js'
Expand All @@ -27,7 +26,7 @@ export function notifyAndArchiveProposal ({ state, proposalHash, proposal, contr
meta: Object,
height: number
}) {
Vue.delete(state.proposals, proposalHash)
delete state.proposals[proposalHash]

// NOTE: we can not make notification for the proposal closal
// in the /proposalVote/sideEffect
Expand Down
4 changes: 2 additions & 2 deletions frontend/model/notifications/periodicNotifications.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use strict'

import sbp from '@sbp/sbp'
import { Vue } from '@common/common.js'
import Vue from 'vue'
// $FlowFixMe
import { objectOf, string, isFunction } from '@model/contracts/misc/flowTyper.js'
import { isFunction, objectOf, string } from '@model/contracts/misc/flowTyper.js'
import { MINS_MILLIS } from '@model/contracts/shared/time.js'

export const PERIODIC_NOTIFICATION_TYPE = {
Expand Down
2 changes: 1 addition & 1 deletion frontend/model/notifications/vuexModule.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

import { Vue } from '@common/common.js'
import Vue from 'vue'
import { cloneDeep } from '~/frontend/model/contracts/shared/giLodash.js'
import * as keys from './mutationKeys.js'
import './selectors.js'
Expand Down
3 changes: 2 additions & 1 deletion frontend/model/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
// state) per: http://vuex.vuejs.org/en/intro.html

import sbp from '@sbp/sbp'
import { Vue, L } from '@common/common.js'
import { L } from '@common/common.js'
import { EVENT_HANDLED, CONTRACT_REGISTERED } from '~/shared/domains/chelonia/events.js'
import { LOGOUT } from '~/frontend/utils/events.js'
import Vue from 'vue'
import Vuex from 'vuex'
import { PROFILE_STATUS, INVITE_INITIAL_CREATOR } from '@model/contracts/shared/constants.js'
import { PAYMENT_NOT_RECEIVED } from '@model/contracts/shared/payments/index.js'
Expand Down
2 changes: 1 addition & 1 deletion frontend/utils/lazyLoadedView.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vue } from '@common/common.js'
import Vue from 'vue'
import ErrorModal from '@views/containers/loading-error/ErrorModal.vue'
import ErrorPage from '@views/containers/loading-error/ErrorPage.vue'
import LoadingModal from '@views/containers/loading-error/LoadingModal.vue'
Expand Down
2 changes: 1 addition & 1 deletion frontend/utils/touchInteractions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vue } from '@common/common.js'
import Vue from 'vue'

if ('ontouchstart' in window || 'msMaxTouchPoints' in navigator) {
import('vue2-touch-events').then(Vue2TouchEvents => Vue.use(Vue2TouchEvents.default))
Expand Down
5 changes: 3 additions & 2 deletions frontend/views/containers/chatroom/ChatMain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@
<script>
import sbp from '@sbp/sbp'
import { mapGetters } from 'vuex'
import { GIMessage } from '~/shared/domains/chelonia/chelonia.js'
import { Vue, L } from '@common/common.js'
import { GIMessage } from '~/shared/domains/chelonia/GIMessage.js'
import { L } from '@common/common.js'
import Vue from 'vue'
import Avatar from '@components/Avatar.vue'
import InfiniteLoading from 'vue-infinite-loading'
import Message from './Message.vue'
Expand Down
3 changes: 2 additions & 1 deletion frontend/views/containers/chatroom/CreatePoll.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@
<script>
import sbp from '@sbp/sbp'
import { mapGetters } from 'vuex'
import { Vue, L } from '@common/common.js'
import { L } from '@common/common.js'
import { validationMixin } from 'vuelidate'
import { required } from 'vuelidate/lib/validators'
import ModalClose from '@components/modal/ModalClose.vue'
import { MESSAGE_TYPES, POLL_TYPES, POLL_MAX_OPTIONS } from '@model/contracts/shared/constants.js'
import { DAYS_MILLIS } from '@model/contracts/shared/time.js'
import Vue from 'vue'
import validationsDebouncedMixins from '@view-utils/validationsDebouncedMixins.js'
import trapFocus from '@utils/trapFocus.js'
Expand Down
3 changes: 2 additions & 1 deletion frontend/views/containers/contributions/PaymentMethods.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ fieldset(data-test='paymentMethods')
<script>
import { mapGetters } from 'vuex'
import { validationMixin } from 'vuelidate'
import { Vue, L } from '@common/common.js'
import { L } from '@common/common.js'
import { maxLength, required } from 'vuelidate/lib/validators'
import { GROUP_PAYMENT_METHOD_MAX_CHAR } from '@model/contracts/shared/constants.js'
import Vue from 'vue'
export default ({
name: 'PaymentMethods',
Expand Down
3 changes: 2 additions & 1 deletion frontend/views/containers/payments/RecordPayment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ modal-base-template(ref='modal' :fullscreen='true' class='has-background' v-if='

<script>
import sbp from '@sbp/sbp'
import { Vue, L } from '@common/common.js'
import { L } from '@common/common.js'
import { mapState, mapGetters } from 'vuex'
import { PAYMENT_PENDING, PAYMENT_COMPLETED, PAYMENT_NOT_RECEIVED, PAYMENT_TYPE_MANUAL } from '@model/contracts/shared/payments/index.js'
import { validationMixin } from 'vuelidate'
import SvgSuccess from '@svgs/success.svg'
import { dateToMonthstamp } from '@model/contracts/shared/time.js'
import ModalBaseTemplate from '@components/modal/ModalBaseTemplate.vue'
import RecordPaymentsList from '@containers/payments/RecordPaymentsList.vue'
import Vue from 'vue'
import BannerScoped from '@components/banners/BannerScoped.vue'
import BannerSimple from '@components/banners/BannerSimple.vue'
import ButtonSubmit from '@components/ButtonSubmit.vue'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ modal-base-template(
</template>

<script>
import { Vue } from '@common/common.js'
import Vue from 'vue'
import ModalBaseTemplate from '@components/modal/ModalBaseTemplate.vue'
import RecordPaymentsList from './RecordPaymentsList.vue'
import QrCode from '@components/QrCode.vue'
Expand Down
2 changes: 1 addition & 1 deletion frontend/views/containers/proposals/AddMembers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ proposal-template(

<script>
import sbp from '@sbp/sbp'
import { Vue } from '@common/common.js'
import Vue from 'vue'
import { mapState, mapGetters } from 'vuex'
import { validationMixin } from 'vuelidate'
import { PROPOSAL_INVITE_MEMBER } from '@model/contracts/shared/constants.js'
Expand Down
2 changes: 1 addition & 1 deletion frontend/views/utils/allowedUrls.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vue } from '@common/common.js'
import Vue from 'vue'

/**
* Table of all well-known safe URLs used in the app UI.
Expand Down
Loading

0 comments on commit 9fd5e16

Please sign in to comment.