Spaces:
Sleeping
Sleeping
const SAFE_PROTOCOLS = [ | |
// The only protocol that's critical to block is javascript: | |
// file: is indeed unsafe in places like Electron, but it's the Electron environment's job to protect against that | |
// Navigating between file: is safe on the web | |
'http:', | |
'https:', | |
'data:', | |
'file:', | |
'mailto:', | |
]; | |
const isSafeURL = (url) => { | |
try { | |
const u = new URL(url, location.href); | |
return SAFE_PROTOCOLS.includes(u.protocol); | |
} catch (e) { | |
return false; | |
} | |
}; | |
const shouldAlwaysOpenInNewTab = (url) => { | |
try { | |
const u = new URL(url, location.href); | |
// Browsers don't allow opening new tabs with data: URIs | |
return u.protocol === 'data:'; | |
} catch (e) { | |
return false; | |
} | |
}; | |
const shouldAlwaysOpenInCurrentTab = (url) => { | |
try { | |
const u = new URL(url, location.href); | |
// If you open a mailto: in a new tab, the browser will convert it to about:blank and just leave an empty tab | |
return u.protocol === 'mailto:'; | |
} catch (e) { | |
return false; | |
} | |
}; | |
const openInNewTab = (url) => { | |
window.open(url); | |
}; | |
const openInCurrentTab = (url) => { | |
location.href = url; | |
}; | |
class SpecialCloudBehaviorsProvider { | |
enable () { | |
this.manager.setVariable(this, 'β url', location.href); | |
document.addEventListener('paste', (e) => { | |
const text = (e.clipboardData || window.clipboardData).getData('text'); | |
this.manager.setVariable(this, 'β pasted', text); | |
}); | |
this.webSocketProvider = this.manager.providers.find(i => typeof i.setProjectId === 'function'); | |
this.initialProjectId = this.webSocketProvider ? this.webSocketProvider.projectId : null; | |
} | |
handleUpdateVariable (name, value) { | |
if (name === 'β redirect') { | |
if (isSafeURL(value)) { | |
if (shouldAlwaysOpenInNewTab(value)) { | |
openInNewTab(value); | |
} else { | |
openInCurrentTab(value); | |
} | |
} | |
} else if (name === 'β open link') { | |
if (isSafeURL(value)) { | |
if (shouldAlwaysOpenInCurrentTab(value)) { | |
openInCurrentTab(value); | |
} else { | |
openInNewTab(value); | |
} | |
} | |
} else if (name === 'β username') { | |
this.manager.parent.setUsername(value); | |
} else if (name === 'β set clipboard') { | |
navigator.clipboard.writeText(value); | |
} else if (name === 'β room id') { | |
if (this.webSocketProvider) { | |
const newId = this.initialProjectId + (value ? `-${value}` : ''); | |
this.webSocketProvider.setProjectId(newId); | |
} | |
} | |
} | |
} | |
export default function ({ scaffolding }) { | |
const provider = new SpecialCloudBehaviorsProvider(); | |
scaffolding.addCloudProvider(provider); | |
scaffolding.addCloudProviderOverride('β url', provider); | |
scaffolding.addCloudProviderOverride('β redirect', provider); | |
scaffolding.addCloudProviderOverride('β open link', provider); | |
scaffolding.addCloudProviderOverride('β username', provider); | |
scaffolding.addCloudProviderOverride('β set clipboard', provider); | |
scaffolding.addCloudProviderOverride('β pasted', provider); | |
scaffolding.addCloudProviderOverride('β room id', provider); | |
} | |