Added MacOS SDK
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,213 @@
|
||||
.chrome-tabs {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
font-size: 10px;
|
||||
height: 40px;
|
||||
/* background: linear-gradient(#dad9da, #d9d8d9); */
|
||||
padding: 0.38em 1.2em 0.0em 1.2em;
|
||||
border-radius: 0.5em 0.5em 0 0;
|
||||
overflow: hidden;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
.chrome-tabs * {
|
||||
box-sizing: inherit;
|
||||
font-family: inherit;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#chrome-tabs-add-tab {
|
||||
background: linear-gradient(0deg, #232330, #282836);
|
||||
box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.4);
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
padding: 5px 10px;
|
||||
margin-top: 9px;
|
||||
margin-right: 3px;
|
||||
border: 0.8px solid #252532;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
z-index: 1000000;
|
||||
height: 24px;
|
||||
color: #c4c2d0 !important;
|
||||
}
|
||||
|
||||
#chrome-tabs-add-tab:active {
|
||||
background: linear-gradient(0deg, #262633, #1e1e29);
|
||||
box-shadow: none;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tabs-bottom-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 0.40em;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 20;
|
||||
border-bottom: 0.8px solid #252532;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tabs-content {
|
||||
position: relative;
|
||||
width: calc(100% - 75px);
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 37px;
|
||||
width: 24em;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
z-index: 1;
|
||||
top: 2px;
|
||||
color: #c4c2d0;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab,
|
||||
.chrome-tabs .chrome-tab * {
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab .chrome-tab-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
|
||||
width: calc(100% - 8px);
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, #212130, #1c1c24);
|
||||
border-radius: 8px 8px 0 0;
|
||||
margin: 2px 4px 4px 4px;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab .chrome-tab-background>svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab .chrome-tab-background>svg .chrome-tab-shadow {
|
||||
fill: none;
|
||||
stroke: rgba(180, 180, 180, 1.0);
|
||||
stroke-width: 1.0px;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab .chrome-tab-background>svg .chrome-tab-background {
|
||||
fill: #c4c2d0;
|
||||
transform: translateX(0.25px) translateY(0.25px);
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab.chrome-tab-current {
|
||||
z-index: 999;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab.chrome-tab-current .chrome-tab-background {
|
||||
background: linear-gradient(180deg, #313141, #282836);
|
||||
/*box-shadow: 0px 1px 2px 1px rgba(0, 0, 0, 0.4); */
|
||||
border: 0.7px solid #292934;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab.chrome-tab-just-added {
|
||||
top: 14px;
|
||||
animation: chrome-tab-just-added 120ms forwards ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
@keyframes chrome-tab-just-added {
|
||||
to {
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.chrome-tabs.chrome-tabs-sorting .chrome-tab:not(.chrome-tab-currently-dragged),
|
||||
.chrome-tabs:not(.chrome-tabs-sorting) .chrome-tab.chrome-tab-just-dragged {
|
||||
transition: transform 120ms ease-in-out;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-favicon,
|
||||
.chrome-tabs .chrome-tab-spinner {
|
||||
position: relative;
|
||||
margin-left: 1.6em;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
background-size: 14px;
|
||||
margin-top: 10px;
|
||||
z-index: 3;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-spinner {
|
||||
content: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJsb2FkZXItMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiCiAgICAgd2lkdGg9IjE0cHgiIGhlaWdodD0iMTRweCIgdmlld0JveD0iMCAwIDUwIDUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MCA1MDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgogIDxwYXRoIGZpbGw9IiM3YTc2OGYiIGQ9Ik00My45MzUsMjUuMTQ1YzAtMTAuMzE4LTguMzY0LTE4LjY4My0xOC42ODMtMTguNjgzYy0xMC4zMTgsMC0xOC42ODMsOC4zNjUtMTguNjgzLDE4LjY4M2g0LjA2OGMwLTguMDcxLDYuNTQzLTE0LjYxNSwxNC42MTUtMTQuNjE1YzguMDcyLDAsMTQuNjE1LDYuNTQzLDE0LjYxNSwxNC42MTVINDMuOTM1eiI+CiAgICA8YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVUeXBlPSJ4bWwiCiAgICAgIGF0dHJpYnV0ZU5hbWU9InRyYW5zZm9ybSIKICAgICAgdHlwZT0icm90YXRlIgogICAgICBmcm9tPSIwIDI1IDI1IgogICAgICB0bz0iMzYwIDI1IDI1IgogICAgICBkdXI9IjAuNnMiCiAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIi8+CiAgICA8L3BhdGg+CiAgPC9zdmc+Cg==");
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-title {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0 0.5em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
margin-top: 9px;
|
||||
max-width: calc(100% - 5em);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-close {
|
||||
position: absolute;
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
border-radius: 50%;
|
||||
z-index: 2;
|
||||
right: 1.4em;
|
||||
top: 11px;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-close::before {
|
||||
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'><path stroke='%235a5a5a' stroke-width='1.3' d='M4 4 L10 10 M10 4 L4 10'></path></svg>");
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-close:hover::before,
|
||||
.chrome-tabs .chrome-tab-close:hover:active::before {
|
||||
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'><path stroke='%23fff' stroke-width='1.3' d='M4 4 L10 10 M10 4 L4 10'></path></svg>");
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-close:hover {
|
||||
background: #e25c4b;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab-close:hover:active {
|
||||
background: #b74a3b;
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab {
|
||||
width: 243px
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab:nth-child(1) {
|
||||
transform: translate3d(0px, 0, 0)
|
||||
}
|
||||
|
||||
.chrome-tabs .chrome-tab:nth-child(2) {
|
||||
transform: translate3d(229px, 0, 0)
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
(function(){
|
||||
const isNodeContext = typeof module !== 'undefined' && typeof module.exports !== 'undefined'
|
||||
if (isNodeContext) {
|
||||
Draggabilly = require('draggabilly')
|
||||
}
|
||||
|
||||
const tabTemplate = `
|
||||
<div class="chrome-tab">
|
||||
<div class="chrome-tab-background">
|
||||
</div>
|
||||
<div class="chrome-tab-favicon"></div>
|
||||
<div class="chrome-tab-spinner"></div>
|
||||
<div class="chrome-tab-title"></div>
|
||||
<div class="chrome-tab-close"></div>
|
||||
</div>
|
||||
`
|
||||
|
||||
const defaultTabProperties = {
|
||||
title: '',
|
||||
favicon: ''
|
||||
}
|
||||
|
||||
let instanceId = 0
|
||||
let tabId = 0
|
||||
|
||||
class ChromeTabs {
|
||||
constructor() {
|
||||
this.draggabillyInstances = []
|
||||
}
|
||||
|
||||
init(el, options) {
|
||||
this.el = el
|
||||
this.options = options
|
||||
|
||||
this.instanceId = instanceId
|
||||
this.el.setAttribute('data-chrome-tabs-instance-id', this.instanceId)
|
||||
instanceId += 1
|
||||
|
||||
this.tabId = tabId
|
||||
|
||||
this.setupStyleEl()
|
||||
this.setupEvents()
|
||||
this.layoutTabs()
|
||||
this.fixZIndexes()
|
||||
this.setupDraggabilly()
|
||||
}
|
||||
|
||||
emit(eventName, data) {
|
||||
this.el.dispatchEvent(new CustomEvent(eventName, { detail: data }))
|
||||
}
|
||||
|
||||
setupStyleEl() {
|
||||
this.animationStyleEl = document.createElement('style')
|
||||
this.el.appendChild(this.animationStyleEl)
|
||||
}
|
||||
|
||||
setupEvents() {
|
||||
window.addEventListener('resize', event => this.layoutTabs())
|
||||
|
||||
document.body.querySelector('#chrome-tabs-add-tab').addEventListener('click', event => this.emit('requestNewTab'))
|
||||
|
||||
this.el.addEventListener('click', ({target}) => {
|
||||
if (target.classList.contains('chrome-tab')) {
|
||||
this.setCurrentTab(target)
|
||||
} else if (target.classList.contains('chrome-tab-close')) {
|
||||
this.emit('requestTabClose', {tabEl: target.parentNode})
|
||||
} else if (target.classList.contains('chrome-tab-title') || target.classList.contains('chrome-tab-favicon')) {
|
||||
this.setCurrentTab(target.parentNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get tabEls() {
|
||||
return Array.prototype.slice.call(this.el.querySelectorAll('.chrome-tab'))
|
||||
}
|
||||
|
||||
get tabContentEl() {
|
||||
return this.el.querySelector('.chrome-tabs-content')
|
||||
}
|
||||
|
||||
get tabWidth() {
|
||||
const tabsContentWidth = this.tabContentEl.clientWidth - this.options.tabOverlapDistance
|
||||
const width = (tabsContentWidth / this.tabEls.length) + this.options.tabOverlapDistance
|
||||
return Math.max(this.options.minWidth, Math.min(this.options.maxWidth, width))
|
||||
}
|
||||
|
||||
get tabEffectiveWidth() {
|
||||
return this.tabWidth - this.options.tabOverlapDistance
|
||||
}
|
||||
|
||||
get tabPositions() {
|
||||
const tabEffectiveWidth = this.tabEffectiveWidth
|
||||
let left = 0
|
||||
let positions = []
|
||||
|
||||
this.tabEls.forEach((tabEl, i) => {
|
||||
positions.push(left)
|
||||
left += tabEffectiveWidth
|
||||
})
|
||||
return positions
|
||||
}
|
||||
|
||||
layoutTabs() {
|
||||
const tabWidth = this.tabWidth
|
||||
|
||||
this.cleanUpPreviouslyDraggedTabs()
|
||||
this.tabEls.forEach((tabEl) => tabEl.style.width = tabWidth + 'px')
|
||||
requestAnimationFrame(() => {
|
||||
let styleHTML = ''
|
||||
this.tabPositions.forEach((left, i) => {
|
||||
styleHTML += `
|
||||
.chrome-tabs[data-chrome-tabs-instance-id="${ this.instanceId }"] .chrome-tab:nth-child(${ i + 1}) {
|
||||
transform: translate3d(${ left }px, 0, 0)
|
||||
}
|
||||
`
|
||||
})
|
||||
this.animationStyleEl.innerHTML = styleHTML
|
||||
})
|
||||
}
|
||||
|
||||
fixZIndexes() {
|
||||
const bottomBarEl = this.el.querySelector('.chrome-tabs-bottom-bar')
|
||||
const tabEls = this.tabEls
|
||||
|
||||
tabEls.forEach((tabEl, i) => {
|
||||
let zIndex = tabEls.length - i
|
||||
|
||||
if (tabEl.classList.contains('chrome-tab-current')) {
|
||||
bottomBarEl.style.zIndex = tabEls.length + 1
|
||||
zIndex = tabEls.length + 2
|
||||
}
|
||||
tabEl.style.zIndex = zIndex
|
||||
})
|
||||
}
|
||||
|
||||
createNewTabEl() {
|
||||
const div = document.createElement('div')
|
||||
div.innerHTML = tabTemplate
|
||||
|
||||
return div.firstElementChild
|
||||
}
|
||||
|
||||
addTab(tabProperties) {
|
||||
const tabEl = this.createNewTabEl()
|
||||
|
||||
tabEl.setAttribute('data-tab-id', tabProperties.id)
|
||||
|
||||
tabEl.classList.add('chrome-tab-just-added')
|
||||
setTimeout(() => tabEl.classList.remove('chrome-tab-just-added'), 500)
|
||||
|
||||
tabProperties = Object.assign({}, defaultTabProperties, tabProperties)
|
||||
this.tabContentEl.appendChild(tabEl)
|
||||
this.updateTab(tabEl, tabProperties)
|
||||
this.emit('tabAdd', { tabEl })
|
||||
this.setCurrentTab(tabEl)
|
||||
this.layoutTabs()
|
||||
this.fixZIndexes()
|
||||
this.setupDraggabilly()
|
||||
}
|
||||
|
||||
setCurrentTab(tabEl) {
|
||||
const currentTab = this.el.querySelector('.chrome-tab-current')
|
||||
if (currentTab) currentTab.classList.remove('chrome-tab-current')
|
||||
tabEl.classList.add('chrome-tab-current')
|
||||
this.fixZIndexes()
|
||||
this.emit('activeTabChange', { tabEl })
|
||||
}
|
||||
|
||||
removeTab(tabEl) {
|
||||
if (tabEl.classList.contains('chrome-tab-current')) {
|
||||
if (tabEl.previousElementSibling) {
|
||||
this.setCurrentTab(tabEl.previousElementSibling)
|
||||
} else if (tabEl.nextElementSibling) {
|
||||
this.setCurrentTab(tabEl.nextElementSibling)
|
||||
}
|
||||
}
|
||||
tabEl.parentNode.removeChild(tabEl)
|
||||
this.emit('tabRemove', { tabEl })
|
||||
this.layoutTabs()
|
||||
this.fixZIndexes()
|
||||
this.setupDraggabilly()
|
||||
}
|
||||
|
||||
updateTab(tabEl, tabProperties) {
|
||||
tabEl.querySelector('.chrome-tab-title').textContent = tabProperties.title
|
||||
tabEl.querySelector('.chrome-tab-favicon').style.backgroundImage = `url('${tabProperties.favicon}')`
|
||||
tabEl.querySelector('.chrome-tab-favicon').style.display = tabProperties.loading ? 'none' : 'inline-block'
|
||||
tabEl.querySelector('.chrome-tab-spinner').style.display = tabProperties.loading ? 'inline-block' : 'none'
|
||||
}
|
||||
|
||||
cleanUpPreviouslyDraggedTabs() {
|
||||
this.tabEls.forEach((tabEl) => tabEl.classList.remove('chrome-tab-just-dragged'))
|
||||
}
|
||||
|
||||
setupDraggabilly() {
|
||||
const tabEls = this.tabEls
|
||||
const tabEffectiveWidth = this.tabEffectiveWidth
|
||||
const tabPositions = this.tabPositions
|
||||
|
||||
this.draggabillyInstances.forEach(draggabillyInstance => draggabillyInstance.destroy())
|
||||
|
||||
tabEls.forEach((tabEl, originalIndex) => {
|
||||
const originalTabPositionX = tabPositions[originalIndex]
|
||||
const draggabillyInstance = new Draggabilly(tabEl, {
|
||||
axis: 'x',
|
||||
containment: this.tabContentEl
|
||||
})
|
||||
|
||||
this.draggabillyInstances.push(draggabillyInstance)
|
||||
|
||||
draggabillyInstance.on('dragStart', () => {
|
||||
this.cleanUpPreviouslyDraggedTabs()
|
||||
tabEl.classList.add('chrome-tab-currently-dragged')
|
||||
this.el.classList.add('chrome-tabs-sorting')
|
||||
this.fixZIndexes()
|
||||
})
|
||||
|
||||
draggabillyInstance.on('dragEnd', () => {
|
||||
const finalTranslateX = parseFloat(tabEl.style.left, 10)
|
||||
tabEl.style.transform = `translate3d(0, 0, 0)`
|
||||
|
||||
// Animate dragged tab back into its place
|
||||
requestAnimationFrame(() => {
|
||||
tabEl.style.left = '0'
|
||||
tabEl.style.transform = `translate3d(${ finalTranslateX }px, 0, 0)`
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
tabEl.classList.remove('chrome-tab-currently-dragged')
|
||||
this.el.classList.remove('chrome-tabs-sorting')
|
||||
|
||||
this.setCurrentTab(tabEl)
|
||||
tabEl.classList.add('chrome-tab-just-dragged')
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
tabEl.style.transform = ''
|
||||
|
||||
this.setupDraggabilly()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
draggabillyInstance.on('dragMove', (event, pointer, moveVector) => {
|
||||
// Current index be computed within the event since it can change during the dragMove
|
||||
const tabEls = this.tabEls
|
||||
const currentIndex = tabEls.indexOf(tabEl)
|
||||
|
||||
const currentTabPositionX = originalTabPositionX + moveVector.x
|
||||
const destinationIndex = Math.max(0, Math.min(tabEls.length, Math.floor((currentTabPositionX + (tabEffectiveWidth / 2)) / tabEffectiveWidth)))
|
||||
|
||||
if (currentIndex !== destinationIndex) {
|
||||
this.animateTabMove(tabEl, currentIndex, destinationIndex)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
animateTabMove(tabEl, originIndex, destinationIndex) {
|
||||
if (destinationIndex < originIndex) {
|
||||
tabEl.parentNode.insertBefore(tabEl, this.tabEls[destinationIndex])
|
||||
} else {
|
||||
tabEl.parentNode.insertBefore(tabEl, this.tabEls[destinationIndex + 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNodeContext) {
|
||||
module.exports = ChromeTabs
|
||||
} else {
|
||||
window.ChromeTabs = ChromeTabs
|
||||
}
|
||||
})()
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="48.625px" height="48.625px" viewBox="0 0 48.625 48.625" style="enable-background:new 0 0 48.625 48.625; fill:#908da2;"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon points="35.432,10.815 35.479,11.176 34.938,11.288 34.866,12.057 35.514,12.057 36.376,11.974 36.821,11.445
|
||||
36.348,11.261 36.089,10.963 35.7,10.333 35.514,9.442 34.783,9.591 34.578,9.905 34.578,10.259 34.93,10.5 "/>
|
||||
<polygon points="34.809,11.111 34.848,10.629 34.419,10.444 33.819,10.583 33.374,11.297 33.374,11.76 33.893,11.76 "/>
|
||||
<path d="M22.459,13.158l-0.132,0.34h-0.639v0.33h0.152c0,0,0.009,0.07,0.022,0.162l0.392-0.033l0.245-0.152l0.064-0.307
|
||||
l0.317-0.027l0.125-0.258l-0.291-0.06L22.459,13.158z"/>
|
||||
<polygon points="20.812,13.757 20.787,14.08 21.25,14.041 21.298,13.717 21.02,13.498 "/>
|
||||
<path d="M48.619,24.061c-0.007-0.711-0.043-1.417-0.11-2.112c-0.225-2.317-0.779-4.538-1.609-6.62
|
||||
c-0.062-0.155-0.119-0.312-0.185-0.465c-1.106-2.613-2.659-4.992-4.56-7.045c-0.125-0.134-0.252-0.266-0.379-0.396
|
||||
c-0.359-0.373-0.728-0.737-1.11-1.086C36.344,2.402,30.604,0,24.312,0C17.967,0,12.186,2.445,7.852,6.44
|
||||
C6.842,7.371,5.914,8.387,5.072,9.475C1.896,13.583,0,18.729,0,24.312c0,13.407,10.907,24.313,24.313,24.313
|
||||
c9.43,0,17.617-5.4,21.647-13.268c0.862-1.682,1.533-3.475,1.985-5.354c0.115-0.477,0.214-0.956,0.3-1.441
|
||||
c0.245-1.381,0.379-2.801,0.379-4.25C48.625,24.228,48.62,24.145,48.619,24.061z M44.043,14.344l0.141-0.158
|
||||
c0.185,0.359,0.358,0.724,0.523,1.094l-0.23-0.009l-0.434,0.06V14.344z M40.53,10.102l0.004-1.086
|
||||
c0.382,0.405,0.75,0.822,1.102,1.254l-0.438,0.652l-1.531-0.014l-0.096-0.319L40.53,10.102z M11.202,7.403V7.362h0.487
|
||||
l0.042-0.167h0.797v0.348l-0.229,0.306h-1.098L11.202,7.403L11.202,7.403z M11.98,8.488c0,0,0.487-0.083,0.529-0.083
|
||||
s0,0.486,0,0.486L11.411,8.96l-0.209-0.25L11.98,8.488z M45.592,18.139h-1.779l-1.084-0.807l-1.141,0.111v0.696h-0.361
|
||||
l-0.39-0.278l-1.976-0.501v-1.28l-2.504,0.195l-0.776,0.417h-0.994L34.1,16.643l-1.207,0.67v1.261l-2.467,1.78l0.205,0.76h0.5
|
||||
L31,21.838l-0.352,0.129l-0.019,1.892l2.132,2.428h0.928l0.056-0.148h1.668l0.481-0.445h0.946l0.519,0.52l1.41,0.146l-0.187,1.875
|
||||
l1.565,2.763l-0.824,1.575l0.056,0.742l0.649,0.647v1.784l0.852,1.146v1.482h0.736c-4.096,5.029-10.33,8.25-17.305,8.25
|
||||
C12.009,46.625,2,36.615,2,24.312c0-3.097,0.636-6.049,1.781-8.732v-0.696l0.798-0.969c0.277-0.523,0.574-1.033,0.891-1.53
|
||||
l0.036,0.405l-0.926,1.125c-0.287,0.542-0.555,1.096-0.798,1.665v1.27l0.927,0.446v1.765l0.889,1.517l0.723,0.111l0.093-0.52
|
||||
l-0.853-1.316l-0.167-1.279h0.5l0.211,1.316l1.233,1.799L7.02,21.27l0.784,1.199l1.947,0.482v-0.315l0.779,0.111l-0.074,0.556
|
||||
l0.612,0.112l0.945,0.258l1.335,1.521l1.705,0.129l0.167,1.391l-1.167,0.816l-0.055,1.242l-0.167,0.76l1.688,2.113l0.129,0.724
|
||||
c0,0,0.612,0.166,0.687,0.166c0.074,0,1.372,0.983,1.372,0.983v3.819l0.463,0.13l-0.315,1.762l0.779,1.039l-0.144,1.746
|
||||
l1.029,1.809l1.321,1.154l1.328,0.024l0.13-0.427l-0.976-0.822l0.056-0.408l0.175-0.5l0.037-0.51l-0.66-0.02l-0.333-0.418
|
||||
l0.548-0.527l0.074-0.398l-0.612-0.175l0.036-0.37l0.872-0.132l1.326-0.637l0.445-0.816l1.391-1.78l-0.316-1.392l0.427-0.741
|
||||
l1.279,0.039l0.861-0.682l0.278-2.686l0.955-1.213l0.167-0.779l-0.871-0.279l-0.575-0.943l-1.965-0.02l-1.558-0.594l-0.074-1.111
|
||||
l-0.52-0.909l-1.409-0.021l-0.814-1.278l-0.723-0.353l-0.037,0.39l-1.316,0.078l-0.482-0.671l-1.373-0.279l-1.131,1.307
|
||||
l-1.78-0.302l-0.129-2.006l-1.299-0.222l0.521-0.984l-0.149-0.565l-1.707,1.141l-1.074-0.131L9.48,21.016l0.234-0.865l0.592-1.091
|
||||
l1.363-0.69l2.632-0.001l-0.007,0.803l0.946,0.44l-0.075-1.372l0.682-0.686l1.376-0.904l0.094-0.636l1.372-1.428l1.459-0.808
|
||||
l-0.129-0.106l0.988-0.93l0.362,0.096l0.166,0.208l0.375-0.416l0.092-0.041l-0.411-0.058l-0.417-0.139v-0.4l0.221-0.181h0.487
|
||||
l0.223,0.098l0.193,0.39l0.236-0.036v-0.034l0.068,0.023l0.684-0.105l0.097-0.334l0.39,0.098v0.362l-0.362,0.249h0.001
|
||||
l0.053,0.397l1.239,0.382c0,0,0.001,0.005,0.003,0.015l0.285-0.024l0.019-0.537l-0.982-0.447l-0.056-0.258l0.815-0.278l0.036-0.78
|
||||
l-0.852-0.519l-0.056-1.315l-1.168,0.574h-0.426l0.112-1.001l-1.59-0.375l-0.658,0.497v1.516l-1.183,0.375l-0.474,0.988
|
||||
l-0.514,0.083v-1.264l-1.112-0.154l-0.556-0.362l-0.224-0.819l1.989-1.164l0.973-0.296l0.098,0.654l0.542-0.028l0.042-0.329
|
||||
l0.567-0.081l0.01-0.115l-0.244-0.101l-0.056-0.348l0.697-0.059l0.421-0.438l0.023-0.032l0.005,0.002l0.128-0.132l1.465-0.185
|
||||
l0.648,0.55l-1.699,0.905l2.162,0.51l0.28-0.723h0.945l0.334-0.63l-0.668-0.167V6.212L22.69,5.284l-1.446,0.167l-0.816,0.427
|
||||
l0.056,1.038l-0.853-0.13L19.5,6.212l0.817-0.742l-1.483-0.074l-0.426,0.129l-0.185,0.5l0.556,0.094l-0.111,0.556l-0.945,0.056
|
||||
l-0.148,0.37l-1.371,0.038c0,0-0.038-0.778-0.093-0.778c-0.055,0,1.075-0.019,1.075-0.019l0.817-0.798l-0.446-0.223l-0.593,0.576
|
||||
l-0.984-0.056l-0.593-0.816h-1.261L12.81,6.008h1.206l0.11,0.353l-0.313,0.291l1.335,0.037l0.204,0.482l-1.503-0.056l-0.073-0.371
|
||||
L12.831,6.54L12.33,6.262l-1.125,0.009C14.888,3.588,19.417,2,24.312,2c5.642,0,10.797,2.109,14.73,5.574l-0.265,0.474
|
||||
l-1.029,0.403l-0.434,0.471l0.1,0.549l0.531,0.074l0.32,0.8l0.916-0.369l0.151,1.07h-0.276l-0.752-0.111l-0.834,0.14l-0.807,1.14
|
||||
l-1.154,0.181l-0.167,0.988l0.487,0.115l-0.141,0.635l-1.146-0.23l-1.051,0.23l-0.223,0.585l0.182,1.228l0.617,0.289l1.035-0.006
|
||||
l0.699-0.063l0.213-0.556l1.092-1.419l0.719,0.147l0.708-0.64l0.132,0.5l1.742,1.175l-0.213,0.286l-0.785-0.042l0.302,0.428
|
||||
l0.483,0.106l0.566-0.236l-0.012-0.682l0.251-0.126l-0.202-0.214l-1.162-0.648l-0.306-0.861h0.966l0.309,0.306l0.832,0.717
|
||||
l0.035,0.867l0.862,0.918l0.321-1.258l0.597-0.326l0.112,1.029l0.583,0.64l1.163-0.02c0.225,0.579,0.427,1.168,0.604,1.769
|
||||
L45.592,18.139z M13.261,11.046l0.584-0.278l0.528,0.126l-0.182,0.709l-0.57,0.181L13.261,11.046z M16.36,12.715v0.459h-1.334
|
||||
l-0.5-0.139l0.125-0.32l0.641-0.265h0.876v0.265H16.36z M16.974,13.355V13.8l-0.334,0.215l-0.416,0.077c0,0,0-0.667,0-0.737
|
||||
H16.974z M16.598,13.174v-0.529l0.459,0.418L16.598,13.174z M16.807,14.244v0.433l-0.319,0.32h-0.709l0.111-0.486l0.335-0.029
|
||||
l0.069-0.167L16.807,14.244z M15.041,13.355h0.737l-0.945,1.321l-0.39-0.209l0.084-0.556L15.041,13.355z M18.059,14.092v0.432
|
||||
H17.35l-0.194-0.28v-0.402h0.056L18.059,14.092z M17.404,13.498l0.202-0.212l0.341,0.212l-0.273,0.225L17.404,13.498z
|
||||
M45.954,19.265l0.07-0.082c0.029,0.126,0.06,0.252,0.088,0.38L45.954,19.265z"/>
|
||||
<path d="M3.782,14.884v0.696c0.243-0.568,0.511-1.122,0.798-1.665L3.782,14.884z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
@@ -0,0 +1,135 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>New Tab</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: #16151d;
|
||||
color: #c4c2d0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: Segoe UI, -apple-system, 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 4em;
|
||||
color: #2d2d3d;
|
||||
margin: 60px auto;
|
||||
margin-top: 0;
|
||||
font-weight: 200;
|
||||
font-family: 'Segoe UI Light', -apple-system, 'Arial', sans-serif;
|
||||
position: fixed;
|
||||
top: 14%;
|
||||
}
|
||||
|
||||
h1 img {
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
div.row {
|
||||
clear: both;
|
||||
width: 652;
|
||||
margin: 0 auto;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
div.row div {
|
||||
background: red;
|
||||
}
|
||||
|
||||
div.row div a {
|
||||
width: 144;
|
||||
height: 144;
|
||||
border: none;
|
||||
border-width: 3px;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
border-radius: 50%;
|
||||
text-decoration: none;
|
||||
color: #c4c2d0;
|
||||
font-size: 0.9em;
|
||||
transition: 0.1s;
|
||||
background: linear-gradient(225deg, #262633, #1e1e29);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.row div a:active {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0px;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
div.row div a.special {
|
||||
background: linear-gradient(45deg, #4085ec, #592dd2, #b16ae7);
|
||||
}
|
||||
|
||||
div.row div a.special span {
|
||||
/*background-color: rgba(225, 220, 255, 0.3); */
|
||||
color: rgb(225, 220, 244);
|
||||
}
|
||||
|
||||
div.row div a span {
|
||||
display: block;
|
||||
height: 1.3em;
|
||||
/*background-color: #FAFAFA; */
|
||||
padding: 8px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
transition: 0.1s;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Courier New;
|
||||
color: #888;
|
||||
width: 610px;
|
||||
margin: 70 auto;
|
||||
}
|
||||
|
||||
div.row div a:hover {
|
||||
background: linear-gradient(225deg, #353549, #262633);
|
||||
color: white;
|
||||
border-color: #833efa;
|
||||
|
||||
/*background: linear-gradient(#E8E8E8, #FFF); */
|
||||
|
||||
}
|
||||
|
||||
div.row div a:hover span {
|
||||
/*background-color: #FCFCFC; */
|
||||
}
|
||||
|
||||
div.row div a.special:hover span {
|
||||
/*background-color: rgba(225, 220, 255, 0.3); */
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.row div a.special:hover {
|
||||
background: linear-gradient(45deg, #4e95ff, #6032e4, #c478ff);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><img src="logo.png" width="300" /></h1>
|
||||
<div id="wrap">
|
||||
<div class="row">
|
||||
<div><a class="special" href="file:///release_notes.html"><span>Release Notes</span></a></div>
|
||||
<div><a href="https://en.wikipedia.com"><span>Wikipedia</span></a></div>
|
||||
<div><a href="https://news.ycombinator.com"><span>Hacker News</span></a></div>
|
||||
<div><a href="https://google.com/"><span>Google</span></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,247 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Release Notes</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: linear-gradient(45deg, #4085ec, #592dd2, #b16ae7);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
font-weight: 300;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
color: #e3e3e3;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, strong, dt {
|
||||
font-weight: 500;
|
||||
color: white;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2em;
|
||||
margin-bottom: 1em;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
a, a:link, a:visited {
|
||||
color: #ffffffd9;
|
||||
font-weight: 500;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
padding: 4px 14px;
|
||||
border-radius: 18px;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-block;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
a:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
background-color: rgb(0 0 0 / 16%);
|
||||
padding: 2px 5px;
|
||||
font-size: 0.9em;
|
||||
border-radius: 4px;
|
||||
color: #ffffffdb;
|
||||
}
|
||||
|
||||
#content {
|
||||
max-width: 800px;
|
||||
width: 90%;
|
||||
margin: 60px auto;
|
||||
padding: 50px;
|
||||
color: white;
|
||||
border-radius: 20px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(255, 255, 255, 0.1) inset;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h4, dt {
|
||||
margin: 0;
|
||||
margin-top: 1.5em;
|
||||
padding: 6px 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 6px 0;
|
||||
margin: 0.5em 0;
|
||||
margin-bottom: 1.5em;
|
||||
line-height: 1.6;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
dd ul {
|
||||
padding: 0;
|
||||
margin: 0.5em 0 1.5em 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.section-list {
|
||||
margin-left: 1.2em;
|
||||
}
|
||||
|
||||
.section-list li {
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
.signature {
|
||||
text-align: right;
|
||||
margin-top: 3em;
|
||||
font-style: italic;
|
||||
opacity: 0.8;
|
||||
color: white;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 1em 2em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="content">
|
||||
|
||||
<h2>Ultralight v1.4.0 Release Notes</h2>
|
||||
|
||||
<p>This major new release updates the engine to latest WebKit, adds support for macOS Apple Silicon and Linux arm64 architectures,
|
||||
enables CSS filters (blurs, saturation, etc.), adds API to composite external image sources, and much more.
|
||||
</p>
|
||||
|
||||
<h3>Changelog</h3>
|
||||
<h4 id="major-improvements">Major Improvements</h4>
|
||||
<ul>
|
||||
<li>Synchronize with upstream WebKit (Safari 16.4.1 / WebKit 615.1.18.100.1)</li>
|
||||
<li>Add support for Apple Silicon architecture on macOS</li>
|
||||
<li>Add support for ARM64 architecture on Linux</li>
|
||||
<li>Add support for WebP and animated WebP videos</li>
|
||||
<li>Add support for compositing external textures / images (new <code>ImageSource</code> API)</li>
|
||||
<li>Add support for CSS filter effects (blurs, saturation, sepia, etc.) (note: not yet natively GPU accelerated, incoming in 1.4.1)</li>
|
||||
<li>Add support for file downloads (see <code>View::set_download_listener</code>)</li>
|
||||
<li>Add support network whitelist / blacklist (see <code>View::set_network_listener</code>)</li>
|
||||
<li>Add support for variable fonts</li>
|
||||
<li>Animation and smooth scroll is now driven by <code>Renderer::RefreshDisplay</code></li>
|
||||
<li>Improve interaction and rendering of dropdown menus</li>
|
||||
<li>Improve support for SVG / Canvas path rendering</li>
|
||||
<li>Improve support for SVG / CSS clips and masks</li>
|
||||
<li>Improve performance of Windows port (now built via Clang)</li>
|
||||
<li>Improve performance of AppCore (now supports high refresh-rate monitors)</li>
|
||||
<li>Improve Chinese-Japanese-Korean text rendering on Linux (AppCore)</li>
|
||||
<li>Improve scroll animation performance</li>
|
||||
<li>Improve performance of the CPU renderer</li>
|
||||
</ul>
|
||||
<h4 id="major-api-changes">Major API Changes</h4>
|
||||
|
||||
<h4>New Classes / Structs:</h4>
|
||||
<ul class="section-list">
|
||||
<li><code>ImageSource</code></li>
|
||||
<li><code>ImageSourceProvider</code></li>
|
||||
<li><code>NetworkListener</code></li>
|
||||
<li><code>NetworkRequest</code></li>
|
||||
<li><code>DownloadListener</code></li>
|
||||
<li><code>ConsoleMessage</code></li>
|
||||
<li><code>ThreadFactory</code></li>
|
||||
</ul>
|
||||
|
||||
<h4>New API Functions:</h4>
|
||||
<ul class="section-list">
|
||||
<li><code>Renderer::RefreshDisplay()</code> (must be called to update animations and scroll)</li>
|
||||
<li><code>View::set_display_id()</code></li>
|
||||
<li><code>View::display_id()</code></li>
|
||||
<li><code>View::set_network_listener()</code></li>
|
||||
<li><code>View::set_download_listener()</code></li>
|
||||
<li><code>View::CancelDownload()</code></li>
|
||||
<li><code>Platform::set_thread_factory()</code></li>
|
||||
<li><code>String::Hash()</code></li>
|
||||
<li><code>String</code> (various comparison operators)</li>
|
||||
<li><code>Monitor::display_id()</code></li>
|
||||
<li><code>Monitor::refresh_rate()</code></li>
|
||||
<li><code>Window::EnableFrameStatistics()</code></li>
|
||||
<li><code>ShowMessageBox()</code></li>
|
||||
</ul>
|
||||
|
||||
<h4>Changes to Existing API:</h4>
|
||||
<ul class="section-list">
|
||||
<li><code>ViewListener::OnAddConsoleMessage()</code> has different parameters</li>
|
||||
<li><code>ViewConfig</code> struct has a new field "<code>display_id</code>"</li>
|
||||
<li><code>MessageSource</code> enum values have changed</li>
|
||||
</ul>
|
||||
|
||||
<h4 id="major-bugfixes">Major Bugfixes</h4>
|
||||
<ul>
|
||||
<li>Fix issue where <code>Config::user_stylesheet</code> would not be applied if HTML doctype was not set</li>
|
||||
<li>Fix issue with alpha blending and opacity in the CPU renderer</li>
|
||||
<li>Fix issue tessellating stroked paths with round and square line-caps in the GPU renderer</li>
|
||||
<li>Fix issue drawing radial gradients in the GPU renderer</li>
|
||||
<li>Fix issue where CSS dashed borders would only be applied to an element when the border radius was rounded</li>
|
||||
<li>Fix issue where files would not be displayed consistently across platforms due to inconsistent mime-type mappings</li>
|
||||
<li>Fix issue validating SSL certificates on Linux and macOS</li>
|
||||
<li>Fix issue where cookies weren't applied to subdomains</li>
|
||||
<li>Fix issue where hard reloads weren't sending no-cache headers</li>
|
||||
<li>Fix issue drawing CSS box shadows outside of the initial View rectangle</li>
|
||||
<li>Fix issue with flickering artifacts on macOS/Metal when a Window has multiple View overlays assigned to it</li>
|
||||
<li>Fix issue compiling on older GCC toolchains</li>
|
||||
<li>Fix crash when rendering certain paths</li>
|
||||
<li>Fix crash in C API due to improper mappings of <code>ULMessageSource</code> and <code>ULMessageLevel</code> enums</li>
|
||||
<li>Fix crash when system page size is less than 16384 bytes</li>
|
||||
<li>Fix crash when switching networks on macOS</li>
|
||||
<li>Fix crash when a remote inspector backend was closed</li>
|
||||
<li>Fix crash when a <code>View</code> was destroyed with dropdown menu open</li>
|
||||
<li>Fix crash when loading Data URIs and certain resource types</li>
|
||||
<li>Fix memory leaks in the CPU renderer</li>
|
||||
<li>Fix memory leak in JavaScriptCore</li>
|
||||
<li>Fix various crashes at shutdown</li>
|
||||
<li>Fix high CPU usage when a WebSocket connection was active</li>
|
||||
<li>Mitigate memory growth when drawing many Canvas elements</li>
|
||||
</ul>
|
||||
|
||||
<h3>Useful Links</h3>
|
||||
<dl>
|
||||
<dt>Website</dt>
|
||||
<dd><a href="https://ultralig.ht">ultralig.ht</a></dd>
|
||||
<dt>Support Docs</dt>
|
||||
<dd><a href="https://docs.ultralig.ht">docs.ultralig.ht</a></dd>
|
||||
</dl>
|
||||
|
||||
<p class="signature">- Ultralight Team</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="14px" height="14px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<path fill="#7a768f" d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z">
|
||||
<animateTransform attributeType="xml"
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 25 25"
|
||||
to="360 25 25"
|
||||
dur="0.6s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 649 B |
@@ -0,0 +1,73 @@
|
||||
* {
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Segoe UI", -apple-system, Ubuntu, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
background: #16151d;
|
||||
color: #c4c2d0;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background: #232330;
|
||||
background: linear-gradient(0deg, #232330, #282836);
|
||||
height: 32px;
|
||||
padding: 4px 9px;
|
||||
border-bottom: 0.8px solid #252532;
|
||||
cursor: default;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#address {
|
||||
border-radius: 24px;
|
||||
border: none;
|
||||
height: 32px;
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
color: #c4c2d0;
|
||||
background-color: #16151d;
|
||||
display: inline-block;
|
||||
padding: 2px 16px 2px 16px;
|
||||
margin-top: 0px;
|
||||
margin-left: 9px;
|
||||
margin-right: 9px;
|
||||
user-select: auto !important;
|
||||
-webkit-user-select: text !important;
|
||||
}
|
||||
|
||||
#address:focus {
|
||||
background-color: #16151d;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: default;
|
||||
fill: rgba(200, 200, 200, 1.0);
|
||||
vertical-align: top;
|
||||
margin-top: -1px;
|
||||
padding: 5px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
#back {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.icon.disabled {
|
||||
|
||||
fill: rgb(99 96 116);
|
||||
}
|
||||
|
||||
svg#icon_defs path {
|
||||
fill: inherit;
|
||||
}
|
||||
|
||||
.icon:not(.disabled):hover {
|
||||
background-color: #343446;
|
||||
border-radius: 100%;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="chrome-tabs.css">
|
||||
<script src="ui.js"></script>
|
||||
<script src="anchorme.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<button id="chrome-tabs-add-tab">+ New Tab</button>
|
||||
<div class="chrome-tabs" data-chrome-tabs-instance-id="0">
|
||||
<div class="chrome-tabs-content"></div>
|
||||
<div class="chrome-tabs-bottom-bar" style="z-index: 3;"></div>
|
||||
</div>
|
||||
|
||||
<svg style="display: none;">
|
||||
<defs>
|
||||
<g id="svg_arrow_back">
|
||||
<path d="M427 277v-42h-260l119 -120l-30 -30l-171 171l171 171l30 -30l-119 -120h260z" />
|
||||
</g>
|
||||
<g id="svg_arrow_forward">
|
||||
<path d="M256 427l171 -171l-171 -171l-30 30l119 120h-260v42h260l-119 120z" />
|
||||
</g>
|
||||
<g id="svg_refresh">
|
||||
<path transform="matrix(1 0 0 -1 0 512)"
|
||||
d="M377 377l50 50v-150h-150l69 69c-23 23 -55 38 -90 38c-71 0 -128 -57 -128 -128s57 -128 128 -128c56 0 104 35 121 85h44c-19 -74 -85 -128 -165 -128c-94 0 -170 77 -170 171s76 171 170 171c47 0 90 -19 121 -50z" />
|
||||
</g>
|
||||
<g id="svg_stop">
|
||||
<path
|
||||
d="M405 375l-119 -119l119 -119l-30 -30l-119 119l-119 -119l-30 30l119 119l-119 119l30 30l119 -119l119 119z" />
|
||||
</g>
|
||||
<g id="svg_tools">
|
||||
<path
|
||||
d="M22.7 19l-9.1-9.1c.9-2.3.4-5-1.5-6.9-2-2-5-2.4-7.4-1.3L9 6 6 9 1.6 4.7C.4 7.1.9 10.1 2.9 12.1c1.9 1.9 4.6 2.4 6.9 1.5l9.1 9.1c.4.4 1 .4 1.4 0l2.3-2.3c.5-.4.5-1.1.1-1.4z" />
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<div id="bar">
|
||||
<span id="back" class="icon disabled">
|
||||
<svg viewBox="0 0 512 512" width="20" height="20">
|
||||
<use xlink:href="#svg_arrow_back" />
|
||||
</svg>
|
||||
</span>
|
||||
<span id="forward" class="icon disabled">
|
||||
<svg viewBox="0 0 512 512" width="20" height="20">
|
||||
<use xlink:href="#svg_arrow_forward" />
|
||||
</svg>
|
||||
</span>
|
||||
<span id="refresh" class="icon">
|
||||
<svg viewBox="0 0 512 512" width="20" height="20">
|
||||
<use xlink:href="#svg_refresh" />
|
||||
</svg>
|
||||
</span>
|
||||
<span id="stop" class="icon" style="display: none;">
|
||||
<svg viewBox="0 0 512 512" width="20" height="20">
|
||||
<use xlink:href="#svg_stop" />
|
||||
</svg>
|
||||
</span>
|
||||
<input onfocus="select_next_mouseup = true;"
|
||||
onmouseup="if (select_next_mouseup) this.select(); select_next_mouseup = false;" type="text"
|
||||
id="address"></input>
|
||||
<span id="toggle-tools" class="icon">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18">
|
||||
<use xlink:href="#svg_tools" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script src="draggabilly.pkgd.min.js"></script>
|
||||
<script src="chrome-tabs.js"></script>
|
||||
<script>
|
||||
var el = document.querySelector('.chrome-tabs')
|
||||
var chromeTabs = new ChromeTabs()
|
||||
var select_next_mouseup = false;
|
||||
var defaultFavicon = "earth.svg";
|
||||
|
||||
chromeTabs.init(el, {
|
||||
tabOverlapDistance: 6,
|
||||
minWidth: 45,
|
||||
maxWidth: 243
|
||||
})
|
||||
|
||||
function addTab(id, title, faviconUrl, isLoading) {
|
||||
chromeTabs.addTab({ id: id, title: title, favicon: defaultFavicon, loading: isLoading });
|
||||
}
|
||||
|
||||
function updateTab(id, title, faviconUrl, isLoading) {
|
||||
const tab = document.querySelector("[data-tab-id='" + id + "']");
|
||||
if (tab)
|
||||
chromeTabs.updateTab(tab, { title: title, favicon: defaultFavicon, loading: isLoading });
|
||||
}
|
||||
|
||||
function closeTab(id) {
|
||||
const tab = document.querySelector("[data-tab-id='" + id + "']");
|
||||
if (tab)
|
||||
chromeTabs.removeTab(tab);
|
||||
}
|
||||
|
||||
function bindCallbacks() {
|
||||
el.addEventListener('requestNewTab', ({ detail }) => OnRequestNewTab());
|
||||
el.addEventListener('requestTabClose', ({ detail }) => OnRequestTabClose(detail.tabEl.getAttribute('data-tab-id')));
|
||||
el.addEventListener('activeTabChange', ({ detail }) => OnActiveTabChange(detail.tabEl.getAttribute('data-tab-id')));
|
||||
document.querySelector('#back').addEventListener('click', event => OnBack());
|
||||
document.querySelector('#forward').addEventListener('click', event => OnForward());
|
||||
document.querySelector('#refresh').addEventListener('click', event => OnRefresh());
|
||||
document.querySelector('#stop').addEventListener('click', event => OnStop());
|
||||
document.querySelector('#toggle-tools').addEventListener('click', event => OnToggleTools());
|
||||
var address = document.querySelector('#address');
|
||||
address.onkeypress = (function (e) {
|
||||
if (e.which == '13') {
|
||||
address.blur();
|
||||
let url = address.value;
|
||||
if (anchorme.validate.url(url) || anchorme.validate.ip(url)) {
|
||||
if (url.toLowerCase().startsWith("http://") || url.toLowerCase().startsWith("https://")) {
|
||||
OnRequestChangeURL(url);
|
||||
} else {
|
||||
OnRequestChangeURL("http://" + url);
|
||||
}
|
||||
} else if (url.toLowerCase().startsWith("file:///")) {
|
||||
OnRequestChangeURL(url);
|
||||
} else if (url.toLowerCase().startsWith("file://")) {
|
||||
OnRequestChangeURL("file:///" + url.substring(7));
|
||||
} else {
|
||||
// Interpret as search
|
||||
OnRequestChangeURL("https://www.google.com/search?q=" + encodeURIComponent(url));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bindCallbacks();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
function updateBack(enable) {
|
||||
if (enable)
|
||||
document.getElementById("back").classList.remove("disabled");
|
||||
else
|
||||
document.getElementById("back").classList.add("disabled");
|
||||
}
|
||||
|
||||
function updateForward(enable) {
|
||||
if (enable)
|
||||
document.getElementById("forward").classList.remove("disabled");
|
||||
else
|
||||
document.getElementById("forward").classList.add("disabled");
|
||||
}
|
||||
|
||||
function updateLoading(is_loading) {
|
||||
if (is_loading) {
|
||||
document.getElementById("refresh").style.display = "none";
|
||||
document.getElementById("stop").style.display = "inline-block";
|
||||
} else {
|
||||
document.getElementById("refresh").style.display = "inline-block";
|
||||
document.getElementById("stop").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function updateURL(url) {
|
||||
document.getElementById('address').value = url;
|
||||
}
|
||||
Reference in New Issue
Block a user