Reduce global variables pollution

This commit is contained in:
Pig Fang 2018-09-09 09:28:05 +08:00
parent 4cd1d91f39
commit 130d16a2f0
36 changed files with 101 additions and 99 deletions

View File

@ -78,4 +78,3 @@ rules:
globals:
blessing: false
__bs_data__: false

View File

@ -44,7 +44,7 @@ export default {
'red',
'black',
],
currentSkin: window.currentSkin
currentSkin: blessing.extra.currentSkin
};
},
methods: {

View File

@ -94,7 +94,7 @@ export default {
captcha: '',
remember: false,
time: Date.now(),
tooManyFails: __bs_data__.tooManyFails,
tooManyFails: blessing.extra.tooManyFails,
infoMsg: '',
warningMsg: '',
pending: false,

View File

@ -131,7 +131,7 @@ export default {
infoMsg: '',
warningMsg: '',
pending: false,
requirePlayer: __bs_data__.player
requirePlayer: blessing.extra.player
}),
methods: {
async submit() {

View File

@ -159,11 +159,11 @@ export default {
size: 0,
uploadAt: '',
public: true,
liked: __bs_data__.inCloset,
canBeDownloaded: __bs_data__.download,
currentUid: __bs_data__.currentUid,
admin: __bs_data__.admin,
uploaderNickName: __bs_data__.nickname,
liked: blessing.extra.inCloset,
canBeDownloaded: blessing.extra.download,
currentUid: blessing.extra.currentUid,
admin: blessing.extra.admin,
uploaderNickName: blessing.extra.nickname,
};
},
computed: {

View File

@ -129,10 +129,10 @@ export default {
files: [],
texture: '',
uploading: false,
textureNameRule: __bs_data__.rule,
privacyNotice: __bs_data__.privacyNotice,
scorePublic: __bs_data__.scorePublic,
scorePrivate: __bs_data__.scorePrivate,
textureNameRule: blessing.extra.rule,
privacyNotice: blessing.extra.privacyNotice,
scorePublic: blessing.extra.scorePublic,
scorePrivate: blessing.extra.scorePrivate,
};
},
computed: {

View File

@ -20,7 +20,7 @@ export default {
name: 'EmailVerification',
data() {
return {
verified: !__bs_data__.unverified,
verified: !blessing.extra.unverified,
pending: false,
};
},

View File

@ -279,8 +279,8 @@ export default {
alex: false,
cape: false
},
playerNameRule: __bs_data__.rule,
playerNameLength: __bs_data__.length
playerNameRule: blessing.extra.rule,
playerNameLength: blessing.extra.length
};
},
beforeMount() {

View File

@ -211,7 +211,7 @@ export default {
currentPassword: '',
deleteConfirm: '',
siteName: blessing.site_name,
isAdmin: __bs_data__.admin
isAdmin: blessing.extra.admin
}),
methods: {
nl2br: str => str.replace(/\n/g, '<br>'),

View File

@ -17,6 +17,4 @@ export function emit(eventName, payload) {
bus[eventName] && bus[eventName].forEach(listener => listener(payload));
}
Object.defineProperty(window, 'bsEmitter', {
get: () => Object.freeze({ on, emit })
});
blessing.event = { on, emit };

View File

@ -7,9 +7,9 @@ import Vue from 'vue';
* @param {object} parameters
* @return {string}
*/
export function trans(key, parameters = {}) {
export function trans(key, parameters = Object.create(null)) {
const segments = key.split('.');
let temp = window.__bs_i18n__ || {};
let temp = blessing.i18n || Object.create(null);
for (const segment of segments) {
if (!temp[segment]) {

View File

@ -69,4 +69,4 @@ Vue.use(_Vue => {
};
});
window.bsAjax = { get, post };
blessing.fetch = { get, post };

View File

@ -79,5 +79,5 @@ export const swal = sweetalert2.mixin({
});
window.toastr = toastr;
window.showModal = showModal;
window.swal = swal;
blessing.notify = { showMsg, showModal };

View File

@ -11,17 +11,28 @@ declare global {
timezone: string
version: string
route: string
}
}
extra: any
i18n: object
interface Window {
bsEmitter: {
on(eventName: string, listener: Function): void
emit(eventName: string, payload: object): void
},
bsAjax: {
get(url: string, params?: object): Promise<object>
post(url: string, data?: object): Promise<object>
fetch: {
get(url: string, params?: object): Promise<object>
post(url: string, data?: object): Promise<object>
}
event: {
on(eventName: string, listener: Function): void
emit(eventName: string, payload: object): void
}
notify: {
showMsg(message: string, type?: string): void
showModal(
message: string,
title?: string,
type?: string,
options?: Partial<{ btnText: string, callback: string, destroyOnClose: boolean }>
)
}
}
}

View File

@ -2,7 +2,7 @@ import Vue from 'vue';
import { mount } from '@vue/test-utils';
import Customization from '@/components/admin/Customization';
window.currentSkin = 'skin-blue';
window.blessing.extra = { currentSkin: 'skin-blue' };
test('preview color', () => {
document.body.classList.add('skin-blue');

View File

@ -6,13 +6,13 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
test('show captcha if too many login fails', () => {
window.__bs_data__ = { tooManyFails: true };
window.blessing.extra = { tooManyFails: true };
const wrapper = mount(Login);
expect(wrapper.find('img').attributes('src')).toMatch(/\/auth\/captcha\?v=\d+/);
});
test('click to refresh captcha', () => {
window.__bs_data__ = { tooManyFails: true };
window.blessing.extra = { tooManyFails: true };
jest.spyOn(Date, 'now');
const wrapper = mount(Login);
wrapper.find('img').trigger('click');
@ -20,7 +20,7 @@ test('click to refresh captcha', () => {
});
test('login', async () => {
window.__bs_data__ = { tooManyFails: false };
window.blessing.extra = { tooManyFails: false };
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: 'fail' })
.mockResolvedValueOnce({ errno: 1, login_fails: 4 })

View File

@ -5,7 +5,7 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
window.__bs_data__ = { player: false };
window.blessing.extra = { player: false };
test('click to refresh captcha', () => {
jest.spyOn(Date, 'now');
@ -15,12 +15,12 @@ test('click to refresh captcha', () => {
});
test('require player name', () => {
window.__bs_data__ = { player: true };
window.blessing.extra = { player: true };
const wrapper = mount(Register);
expect(wrapper.findAll('[type="text"]').at(0).attributes('placeholder')).toBe('auth.player-name');
window.__bs_data__ = { player: false };
window.blessing.extra = { player: false };
});
test('register', async () => {
@ -94,7 +94,7 @@ test('register', async () => {
});
test('register with player name', async () => {
window.__bs_data__ = { player: true };
window.blessing.extra = { player: true };
Vue.prototype.$http.post.mockResolvedValue({ errno: 0, msg: 'ok' });
const wrapper = mount(Register);
const button = wrapper.find('button');

View File

@ -7,7 +7,7 @@ import toastr from 'toastr';
jest.mock('@/js/notify');
window.__bs_data__ = {
window.blessing.extra = {
download: true,
currentUid: 0,
admin: false,
@ -35,7 +35,7 @@ test('button for adding to closet should be disabled if not auth', () => {
test('button for adding to closet should be disabled if auth', () => {
Vue.prototype.$http.get.mockResolvedValue({});
Object.assign(window.__bs_data__, { inCloset: true, currentUid: 1 });
Object.assign(window.blessing.extra, { inCloset: true, currentUid: 1 });
const wrapper = mount(Show, {
mocks: {
$route: ['/skinlib/show/1', '1']
@ -82,7 +82,7 @@ test('render basic information', async () => {
});
test('render action text of editing texture name', async () => {
Object.assign(window.__bs_data__, { admin: true });
Object.assign(window.blessing.extra, { admin: true });
Vue.prototype.$http.get.mockResolvedValue({ uploader: 1, name: 'name' });
let wrapper = mount(Show, {
@ -93,7 +93,7 @@ test('render action text of editing texture name', async () => {
await wrapper.vm.$nextTick();
expect(wrapper.contains('small')).toBeTrue();
Object.assign(window.__bs_data__, { currentUid: 2, admin: false });
Object.assign(window.blessing.extra, { currentUid: 2, admin: false });
wrapper = mount(Show, {
mocks: {
$route: ['/skinlib/show/1', '1']
@ -104,7 +104,7 @@ test('render action text of editing texture name', async () => {
});
test('render nickname of uploader', () => {
Object.assign(window.__bs_data__, { nickname: null });
Object.assign(window.blessing.extra, { nickname: null });
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Show, {
mocks: {
@ -115,7 +115,7 @@ test('render nickname of uploader', () => {
});
test('operation panel should not be rendered if not auth', () => {
Object.assign(window.__bs_data__, { currentUid: 0 });
Object.assign(window.blessing.extra, { currentUid: 0 });
Vue.prototype.$http.get.mockResolvedValue({});
const wrapper = mount(Show, {
mocks: {
@ -126,7 +126,7 @@ test('operation panel should not be rendered if not auth', () => {
});
test('link to downloading texture', async () => {
Object.assign(window.__bs_data__, { download: false });
Object.assign(window.blessing.extra, { download: false });
Vue.prototype.$http.get.mockResolvedValue({ hash: '123' });
const wrapper = mount(Show, {
mocks: {
@ -139,7 +139,7 @@ test('link to downloading texture', async () => {
});
test('add to closet', async () => {
Object.assign(window.__bs_data__, { currentUid: 1, inCloset: false });
Object.assign(window.blessing.extra, { currentUid: 1, inCloset: false });
Vue.prototype.$http.get.mockResolvedValue({ name: 'wow', likes: 2 });
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
@ -179,7 +179,7 @@ test('add to closet', async () => {
});
test('remove from closet', async () => {
Object.assign(window.__bs_data__, { currentUid: 1, inCloset: true });
Object.assign(window.blessing.extra, { currentUid: 1, inCloset: true });
Vue.prototype.$http.get.mockResolvedValue({ likes: 2 });
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
@ -213,7 +213,7 @@ test('remove from closet', async () => {
});
test('change texture name', async () => {
Object.assign(window.__bs_data__, { admin: true });
Object.assign(window.blessing.extra, { admin: true });
Vue.prototype.$http.get.mockResolvedValue({ name: 'old-name' });
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })

View File

@ -10,7 +10,7 @@ jest.mock('toastr');
jest.mock('@/js/notify');
jest.mock('@/js/net');
window.__bs_data__ = {
window.blessing.extra = {
textureNameRule: 'rule',
privacyNotice: 'privacyNotice',
scorePrivate: 10,

View File

@ -8,7 +8,7 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
window.__bs_data__ = { unverified: false };
window.blessing.extra = { unverified: false };
test('fetch closet data before mount', () => {
Vue.prototype.$http.get.mockResolvedValue({});

View File

@ -6,7 +6,7 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
window.__bs_data__ = { unverified: false };
window.blessing.extra = { unverified: false };
function scoreInfo(data = {}) {
return {

View File

@ -6,13 +6,13 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
test('message box should not be render if verified', () => {
window.__bs_data__ = { unverified: false };
window.blessing.extra = { unverified: false };
const wrapper = mount(EmailVerification);
expect(wrapper.isEmpty()).toBeTrue();
});
test('resend email', async () => {
window.__bs_data__ = { unverified: true };
window.blessing.extra = { unverified: true };
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: '1' })
.mockResolvedValueOnce({ errno: 0, msg: '0' });

View File

@ -7,7 +7,7 @@ import { swal } from '@/js/notify';
jest.mock('toastr');
jest.mock('@/js/notify');
window.__bs_data__ = {
window.blessing.extra = {
rule: 'rule',
length: 'length'
};

View File

@ -7,14 +7,14 @@ import { swal } from '@/js/notify';
jest.mock('@/js/notify');
window.__bs_data__ = { unverified: false };
window.blessing.extra = { unverified: false };
test('computed values', () => {
window.__bs_data__ = { admin: true };
window.blessing.extra = { admin: true };
const wrapper = mount(Profile);
expect(wrapper.vm.siteName).toBe('Blessing Skin');
expect(wrapper.vm.isAdmin).toBeTrue();
window.__bs_data__ = { admin: false };
window.blessing.extra = { admin: false };
expect(mount(Profile).vm.isAdmin).toBeFalse();
});
@ -152,7 +152,7 @@ test('change email', async () => {
});
test('delete account', async () => {
window.__bs_data__ = { admin: true };
window.blessing.extra = { admin: true };
swal.mockResolvedValue();
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: 'w' })

View File

@ -6,7 +6,7 @@ test('mount to global', () => {
});
test('translate text', () => {
window.__bs_i18n__ = { a: { b: { c: 'text', d: 'Hi, :name!' } } };
window.blessing.i18n = { a: { b: { c: 'text', d: 'Hi, :name!' } } };
expect(trans('a.b.c')).toBe('text');
expect(trans('a.b.d')).toBe('Hi, :name!');
expect(trans('a.b.d', { name: 'me' })).toBe('Hi, me!');

View File

@ -1,3 +1,3 @@
import lang from './front-end.yml';
window.__bs_i18n__ = Object.assign(window.__bs_i18n__ || {}, lang);
blessing.i18n = Object.assign(blessing.i18n || Object.create(null), lang);

View File

@ -1,3 +1,3 @@
import lang from './front-end.yml';
window.__bs_i18n__ = Object.assign(window.__bs_i18n__ || {}, lang);
blessing.i18n = Object.assign(blessing.i18n || Object.create(null), lang);

View File

@ -37,7 +37,9 @@
</div><!-- /.content-wrapper -->
<script>
var currentSkin = "{{ option('color_scheme') }}";
blessing.extra = {
currentSkin: "{{ option('color_scheme') }}"
};
</script>
@endsection

View File

@ -25,11 +25,9 @@
<!-- /.login-box -->
<script>
Object.defineProperty(window, '__bs_data__', {
Object.defineProperty(blessing, 'extra', {
configurable: false,
get: function () {
return Object.freeze({ tooManyFails: {{ cache(sha1('login_fails_'.get_client_ip())) > 3 ? 'true' : 'false' }} })
}
get: () => Object.freeze({ tooManyFails: {{ cache(sha1('login_fails_'.get_client_ip())) > 3 ? 'true' : 'false' }} })
})
</script>

View File

@ -19,12 +19,10 @@
<!-- /.register-box -->
<script>
Object.defineProperty(window, '__bs_data__', {
get: function () {
return Object.freeze({
player: {{ option('register_with_player_name') ? 'true' : 'false' }},
})
},
Object.defineProperty(blessing, 'extra', {
get: () => Object.freeze({
player: {{ option('register_with_player_name') ? 'true' : 'false' }},
}),
configurable: false
})
</script>

View File

@ -41,17 +41,15 @@
</div><!-- /.content-wrapper -->
<script>
Object.defineProperty(window, '__bs_data__', {
Object.defineProperty(blessing, 'extra', {
configurable: false,
get: function () {
return Object.freeze({
download: {{ option('allow_downloading_texture') ? 'true' : 'false' }},
currentUid: {{ is_null($user) ? '0' : $user->uid }},
admin: {{ $user && $user->isAdmin() ? 'true' : 'false' }},
inCloset: {{ $user && $user->getCloset()->has($texture->tid) ? 'true' : 'false' }},
nickname: @php echo ($up = app('users')->get($texture->uploader)) ? '"'.$up->nickname.'"' : 'null' @endphp
})
}
get: () => Object.freeze({
download: {{ option('allow_downloading_texture') ? 'true' : 'false' }},
currentUid: {{ is_null($user) ? '0' : $user->uid }},
admin: {{ $user && $user->isAdmin() ? 'true' : 'false' }},
inCloset: {{ $user && $user->getCloset()->has($texture->tid) ? 'true' : 'false' }},
nickname: @php echo ($up = app('users')->get($texture->uploader)) ? '"'.$up->nickname.'"' : 'null' @endphp
})
})
</script>

View File

@ -19,7 +19,7 @@
</div><!-- /.content-wrapper -->
<script>
var __bs_data__ = {
blessing.extra = {
rule: "{{ option('texture_name_regexp') ? trans('skinlib.upload.name-rule-regexp', compact('regexp')) : trans('skinlib.upload.name-rule') }}",
privacyNotice: "@lang('skinlib.upload.private-score-notice', ['score' => option('private_score_per_storage')])",
scorePublic: {{ option('score_per_storage') }},

View File

@ -22,11 +22,10 @@
</div><!-- /.content-wrapper -->
<script>
Object.defineProperty(window, '__bs_data__', {
value: Object.freeze({
Object.defineProperty(blessing, 'extra', {
get: () => Object.freeze({
unverified: {{ option('require_verification') && !$user->verified ? 'true' : 'false' }}
}),
writable: false
})
})
</script>
@endsection

View File

@ -74,11 +74,10 @@
</div><!-- /.modal -->
<script>
Object.defineProperty(window, '__bs_data__', {
value: Object.freeze({
Object.defineProperty(blessing, 'extra', {
get: () => Object.freeze({
unverified: {{ option('require_verification') && !$user->verified ? 'true' : 'false' }}
}),
writable: false
})
})
</script>
@endsection

View File

@ -18,7 +18,7 @@
</div><!-- /.content-wrapper -->
<script>
var __bs_data__ = {
blessing.extra = {
rule: "@lang('user.player.player-name-rule.'.option('player_name_rule'))",
length: "@lang('user.player.player-name-length', ['min' => option('player_name_length_min'), 'max' => option('player_name_length_max')])"
}

View File

@ -18,12 +18,12 @@
</div><!-- /.content-wrapper -->
<script>
Object.defineProperty(window, '__bs_data__', {
value: Object.freeze({
Object.defineProperty(blessing, 'extra', {
configurable: false,
get: () => Object.freeze({
admin: {{ (string) $user->isAdmin() ?: 'false' }},
unverified: {{ option('require_verification') && !$user->verified ? 'true' : 'false' }}
}),
writable: false
})
</script>
@endsection