Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
quasseldroid-landing
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Janne Mareike Koschinski
quasseldroid-landing
Commits
0649a840
Commit
0649a840
authored
7 years ago
by
Janne Mareike Koschinski
Browse files
Options
Downloads
Patches
Plain Diff
Added polyfill and meta info
parent
742a6ceb
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
assets/js/intersectionobserver.js
+724
-0
724 additions, 0 deletions
assets/js/intersectionobserver.js
index.html
+2
-2
2 additions, 2 deletions
index.html
index.pug
+4
-2
4 additions, 2 deletions
index.pug
with
730 additions
and
4 deletions
assets/js/intersectionobserver.js
0 → 100644
+
724
−
0
View file @
0649a840
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(
function
(
window
,
document
)
{
'
use strict
'
;
// Exits early if all IntersectionObserver and IntersectionObserverEntry
// features are natively supported.
if
(
'
IntersectionObserver
'
in
window
&&
'
IntersectionObserverEntry
'
in
window
&&
'
intersectionRatio
'
in
window
.
IntersectionObserverEntry
.
prototype
)
{
// Minimal polyfill for Edge 15's lack of `isIntersecting`
// See: https://github.com/w3c/IntersectionObserver/issues/211
if
(
!
(
'
isIntersecting
'
in
window
.
IntersectionObserverEntry
.
prototype
))
{
Object
.
defineProperty
(
window
.
IntersectionObserverEntry
.
prototype
,
'
isIntersecting
'
,
{
get
:
function
()
{
return
this
.
intersectionRatio
>
0
;
}
});
}
return
;
}
/**
* An IntersectionObserver registry. This registry exists to hold a strong
* reference to IntersectionObserver instances currently observering a target
* element. Without this registry, instances without another reference may be
* garbage collected.
*/
var
registry
=
[];
/**
* Creates the global IntersectionObserverEntry constructor.
* https://w3c.github.io/IntersectionObserver/#intersection-observer-entry
* @param {Object} entry A dictionary of instance properties.
* @constructor
*/
function
IntersectionObserverEntry
(
entry
)
{
this
.
time
=
entry
.
time
;
this
.
target
=
entry
.
target
;
this
.
rootBounds
=
entry
.
rootBounds
;
this
.
boundingClientRect
=
entry
.
boundingClientRect
;
this
.
intersectionRect
=
entry
.
intersectionRect
||
getEmptyRect
();
this
.
isIntersecting
=
!!
entry
.
intersectionRect
;
// Calculates the intersection ratio.
var
targetRect
=
this
.
boundingClientRect
;
var
targetArea
=
targetRect
.
width
*
targetRect
.
height
;
var
intersectionRect
=
this
.
intersectionRect
;
var
intersectionArea
=
intersectionRect
.
width
*
intersectionRect
.
height
;
// Sets intersection ratio.
if
(
targetArea
)
{
this
.
intersectionRatio
=
intersectionArea
/
targetArea
;
}
else
{
// If area is zero and is intersecting, sets to 1, otherwise to 0
this
.
intersectionRatio
=
this
.
isIntersecting
?
1
:
0
;
}
}
/**
* Creates the global IntersectionObserver constructor.
* https://w3c.github.io/IntersectionObserver/#intersection-observer-interface
* @param {Function} callback The function to be invoked after intersection
* changes have queued. The function is not invoked if the queue has
* been emptied by calling the `takeRecords` method.
* @param {Object=} opt_options Optional configuration options.
* @constructor
*/
function
IntersectionObserver
(
callback
,
opt_options
)
{
var
options
=
opt_options
||
{};
if
(
typeof
callback
!=
'
function
'
)
{
throw
new
Error
(
'
callback must be a function
'
);
}
if
(
options
.
root
&&
options
.
root
.
nodeType
!=
1
)
{
throw
new
Error
(
'
root must be an Element
'
);
}
// Binds and throttles `this._checkForIntersections`.
this
.
_checkForIntersections
=
throttle
(
this
.
_checkForIntersections
.
bind
(
this
),
this
.
THROTTLE_TIMEOUT
);
// Private properties.
this
.
_callback
=
callback
;
this
.
_observationTargets
=
[];
this
.
_queuedEntries
=
[];
this
.
_rootMarginValues
=
this
.
_parseRootMargin
(
options
.
rootMargin
);
// Public properties.
this
.
thresholds
=
this
.
_initThresholds
(
options
.
threshold
);
this
.
root
=
options
.
root
||
null
;
this
.
rootMargin
=
this
.
_rootMarginValues
.
map
(
function
(
margin
)
{
return
margin
.
value
+
margin
.
unit
;
}).
join
(
'
'
);
}
/**
* The minimum interval within which the document will be checked for
* intersection changes.
*/
IntersectionObserver
.
prototype
.
THROTTLE_TIMEOUT
=
100
;
/**
* The frequency in which the polyfill polls for intersection changes.
* this can be updated on a per instance basis and must be set prior to
* calling `observe` on the first target.
*/
IntersectionObserver
.
prototype
.
POLL_INTERVAL
=
null
;
/**
* Starts observing a target element for intersection changes based on
* the thresholds values.
* @param {Element} target The DOM element to observe.
*/
IntersectionObserver
.
prototype
.
observe
=
function
(
target
)
{
// If the target is already being observed, do nothing.
if
(
this
.
_observationTargets
.
some
(
function
(
item
)
{
return
item
.
element
==
target
;
}))
{
return
;
}
if
(
!
(
target
&&
target
.
nodeType
==
1
))
{
throw
new
Error
(
'
target must be an Element
'
);
}
this
.
_registerInstance
();
this
.
_observationTargets
.
push
({
element
:
target
,
entry
:
null
});
this
.
_monitorIntersections
();
this
.
_checkForIntersections
();
};
/**
* Stops observing a target element for intersection changes.
* @param {Element} target The DOM element to observe.
*/
IntersectionObserver
.
prototype
.
unobserve
=
function
(
target
)
{
this
.
_observationTargets
=
this
.
_observationTargets
.
filter
(
function
(
item
)
{
return
item
.
element
!=
target
;
});
if
(
!
this
.
_observationTargets
.
length
)
{
this
.
_unmonitorIntersections
();
this
.
_unregisterInstance
();
}
};
/**
* Stops observing all target elements for intersection changes.
*/
IntersectionObserver
.
prototype
.
disconnect
=
function
()
{
this
.
_observationTargets
=
[];
this
.
_unmonitorIntersections
();
this
.
_unregisterInstance
();
};
/**
* Returns any queue entries that have not yet been reported to the
* callback and clears the queue. This can be used in conjunction with the
* callback to obtain the absolute most up-to-date intersection information.
* @return {Array} The currently queued entries.
*/
IntersectionObserver
.
prototype
.
takeRecords
=
function
()
{
var
records
=
this
.
_queuedEntries
.
slice
();
this
.
_queuedEntries
=
[];
return
records
;
};
/**
* Accepts the threshold value from the user configuration object and
* returns a sorted array of unique threshold values. If a value is not
* between 0 and 1 and error is thrown.
* @private
* @param {Array|number=} opt_threshold An optional threshold value or
* a list of threshold values, defaulting to [0].
* @return {Array} A sorted list of unique and valid threshold values.
*/
IntersectionObserver
.
prototype
.
_initThresholds
=
function
(
opt_threshold
)
{
var
threshold
=
opt_threshold
||
[
0
];
if
(
!
Array
.
isArray
(
threshold
))
threshold
=
[
threshold
];
return
threshold
.
sort
().
filter
(
function
(
t
,
i
,
a
)
{
if
(
typeof
t
!=
'
number
'
||
isNaN
(
t
)
||
t
<
0
||
t
>
1
)
{
throw
new
Error
(
'
threshold must be a number between 0 and 1 inclusively
'
);
}
return
t
!==
a
[
i
-
1
];
});
};
/**
* Accepts the rootMargin value from the user configuration object
* and returns an array of the four margin values as an object containing
* the value and unit properties. If any of the values are not properly
* formatted or use a unit other than px or %, and error is thrown.
* @private
* @param {string=} opt_rootMargin An optional rootMargin value,
* defaulting to '0px'.
* @return {Array<Object>} An array of margin objects with the keys
* value and unit.
*/
IntersectionObserver
.
prototype
.
_parseRootMargin
=
function
(
opt_rootMargin
)
{
var
marginString
=
opt_rootMargin
||
'
0px
'
;
var
margins
=
marginString
.
split
(
/
\s
+/
).
map
(
function
(
margin
)
{
var
parts
=
/^
(
-
?\d
*
\.?\d
+
)(
px|%
)
$/
.
exec
(
margin
);
if
(
!
parts
)
{
throw
new
Error
(
'
rootMargin must be specified in pixels or percent
'
);
}
return
{
value
:
parseFloat
(
parts
[
1
]),
unit
:
parts
[
2
]};
});
// Handles shorthand.
margins
[
1
]
=
margins
[
1
]
||
margins
[
0
];
margins
[
2
]
=
margins
[
2
]
||
margins
[
0
];
margins
[
3
]
=
margins
[
3
]
||
margins
[
1
];
return
margins
;
};
/**
* Starts polling for intersection changes if the polling is not already
* happening, and if the page's visibilty state is visible.
* @private
*/
IntersectionObserver
.
prototype
.
_monitorIntersections
=
function
()
{
if
(
!
this
.
_monitoringIntersections
)
{
this
.
_monitoringIntersections
=
true
;
// If a poll interval is set, use polling instead of listening to
// resize and scroll events or DOM mutations.
if
(
this
.
POLL_INTERVAL
)
{
this
.
_monitoringInterval
=
setInterval
(
this
.
_checkForIntersections
,
this
.
POLL_INTERVAL
);
}
else
{
addEvent
(
window
,
'
resize
'
,
this
.
_checkForIntersections
,
true
);
addEvent
(
document
,
'
scroll
'
,
this
.
_checkForIntersections
,
true
);
if
(
'
MutationObserver
'
in
window
)
{
this
.
_domObserver
=
new
MutationObserver
(
this
.
_checkForIntersections
);
this
.
_domObserver
.
observe
(
document
,
{
attributes
:
true
,
childList
:
true
,
characterData
:
true
,
subtree
:
true
});
}
}
}
};
/**
* Stops polling for intersection changes.
* @private
*/
IntersectionObserver
.
prototype
.
_unmonitorIntersections
=
function
()
{
if
(
this
.
_monitoringIntersections
)
{
this
.
_monitoringIntersections
=
false
;
clearInterval
(
this
.
_monitoringInterval
);
this
.
_monitoringInterval
=
null
;
removeEvent
(
window
,
'
resize
'
,
this
.
_checkForIntersections
,
true
);
removeEvent
(
document
,
'
scroll
'
,
this
.
_checkForIntersections
,
true
);
if
(
this
.
_domObserver
)
{
this
.
_domObserver
.
disconnect
();
this
.
_domObserver
=
null
;
}
}
};
/**
* Scans each observation target for intersection changes and adds them
* to the internal entries queue. If new entries are found, it
* schedules the callback to be invoked.
* @private
*/
IntersectionObserver
.
prototype
.
_checkForIntersections
=
function
()
{
var
rootIsInDom
=
this
.
_rootIsInDom
();
var
rootRect
=
rootIsInDom
?
this
.
_getRootRect
()
:
getEmptyRect
();
this
.
_observationTargets
.
forEach
(
function
(
item
)
{
var
target
=
item
.
element
;
var
targetRect
=
getBoundingClientRect
(
target
);
var
rootContainsTarget
=
this
.
_rootContainsTarget
(
target
);
var
oldEntry
=
item
.
entry
;
var
intersectionRect
=
rootIsInDom
&&
rootContainsTarget
&&
this
.
_computeTargetAndRootIntersection
(
target
,
rootRect
);
var
newEntry
=
item
.
entry
=
new
IntersectionObserverEntry
({
time
:
now
(),
target
:
target
,
boundingClientRect
:
targetRect
,
rootBounds
:
rootRect
,
intersectionRect
:
intersectionRect
});
if
(
!
oldEntry
)
{
this
.
_queuedEntries
.
push
(
newEntry
);
}
else
if
(
rootIsInDom
&&
rootContainsTarget
)
{
// If the new entry intersection ratio has crossed any of the
// thresholds, add a new entry.
if
(
this
.
_hasCrossedThreshold
(
oldEntry
,
newEntry
))
{
this
.
_queuedEntries
.
push
(
newEntry
);
}
}
else
{
// If the root is not in the DOM or target is not contained within
// root but the previous entry for this target had an intersection,
// add a new record indicating removal.
if
(
oldEntry
&&
oldEntry
.
isIntersecting
)
{
this
.
_queuedEntries
.
push
(
newEntry
);
}
}
},
this
);
if
(
this
.
_queuedEntries
.
length
)
{
this
.
_callback
(
this
.
takeRecords
(),
this
);
}
};
/**
* Accepts a target and root rect computes the intersection between then
* following the algorithm in the spec.
* TODO(philipwalton): at this time clip-path is not considered.
* https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo
* @param {Element} target The target DOM element
* @param {Object} rootRect The bounding rect of the root after being
* expanded by the rootMargin value.
* @return {?Object} The final intersection rect object or undefined if no
* intersection is found.
* @private
*/
IntersectionObserver
.
prototype
.
_computeTargetAndRootIntersection
=
function
(
target
,
rootRect
)
{
// If the element isn't displayed, an intersection can't happen.
if
(
window
.
getComputedStyle
(
target
).
display
==
'
none
'
)
return
;
var
targetRect
=
getBoundingClientRect
(
target
);
var
intersectionRect
=
targetRect
;
var
parent
=
getParentNode
(
target
);
var
atRoot
=
false
;
while
(
!
atRoot
)
{
var
parentRect
=
null
;
var
parentComputedStyle
=
parent
.
nodeType
==
1
?
window
.
getComputedStyle
(
parent
)
:
{};
// If the parent isn't displayed, an intersection can't happen.
if
(
parentComputedStyle
.
display
==
'
none
'
)
return
;
if
(
parent
==
this
.
root
||
parent
==
document
)
{
atRoot
=
true
;
parentRect
=
rootRect
;
}
else
{
// If the element has a non-visible overflow, and it's not the <body>
// or <html> element, update the intersection rect.
// Note: <body> and <html> cannot be clipped to a rect that's not also
// the document rect, so no need to compute a new intersection.
if
(
parent
!=
document
.
body
&&
parent
!=
document
.
documentElement
&&
parentComputedStyle
.
overflow
!=
'
visible
'
)
{
parentRect
=
getBoundingClientRect
(
parent
);
}
}
// If either of the above conditionals set a new parentRect,
// calculate new intersection data.
if
(
parentRect
)
{
intersectionRect
=
computeRectIntersection
(
parentRect
,
intersectionRect
);
if
(
!
intersectionRect
)
break
;
}
parent
=
getParentNode
(
parent
);
}
return
intersectionRect
;
};
/**
* Returns the root rect after being expanded by the rootMargin value.
* @return {Object} The expanded root rect.
* @private
*/
IntersectionObserver
.
prototype
.
_getRootRect
=
function
()
{
var
rootRect
;
if
(
this
.
root
)
{
rootRect
=
getBoundingClientRect
(
this
.
root
);
}
else
{
// Use <html>/<body> instead of window since scroll bars affect size.
var
html
=
document
.
documentElement
;
var
body
=
document
.
body
;
rootRect
=
{
top
:
0
,
left
:
0
,
right
:
html
.
clientWidth
||
body
.
clientWidth
,
width
:
html
.
clientWidth
||
body
.
clientWidth
,
bottom
:
html
.
clientHeight
||
body
.
clientHeight
,
height
:
html
.
clientHeight
||
body
.
clientHeight
};
}
return
this
.
_expandRectByRootMargin
(
rootRect
);
};
/**
* Accepts a rect and expands it by the rootMargin value.
* @param {Object} rect The rect object to expand.
* @return {Object} The expanded rect.
* @private
*/
IntersectionObserver
.
prototype
.
_expandRectByRootMargin
=
function
(
rect
)
{
var
margins
=
this
.
_rootMarginValues
.
map
(
function
(
margin
,
i
)
{
return
margin
.
unit
==
'
px
'
?
margin
.
value
:
margin
.
value
*
(
i
%
2
?
rect
.
width
:
rect
.
height
)
/
100
;
});
var
newRect
=
{
top
:
rect
.
top
-
margins
[
0
],
right
:
rect
.
right
+
margins
[
1
],
bottom
:
rect
.
bottom
+
margins
[
2
],
left
:
rect
.
left
-
margins
[
3
]
};
newRect
.
width
=
newRect
.
right
-
newRect
.
left
;
newRect
.
height
=
newRect
.
bottom
-
newRect
.
top
;
return
newRect
;
};
/**
* Accepts an old and new entry and returns true if at least one of the
* threshold values has been crossed.
* @param {?IntersectionObserverEntry} oldEntry The previous entry for a
* particular target element or null if no previous entry exists.
* @param {IntersectionObserverEntry} newEntry The current entry for a
* particular target element.
* @return {boolean} Returns true if a any threshold has been crossed.
* @private
*/
IntersectionObserver
.
prototype
.
_hasCrossedThreshold
=
function
(
oldEntry
,
newEntry
)
{
// To make comparing easier, an entry that has a ratio of 0
// but does not actually intersect is given a value of -1
var
oldRatio
=
oldEntry
&&
oldEntry
.
isIntersecting
?
oldEntry
.
intersectionRatio
||
0
:
-
1
;
var
newRatio
=
newEntry
.
isIntersecting
?
newEntry
.
intersectionRatio
||
0
:
-
1
;
// Ignore unchanged ratios
if
(
oldRatio
===
newRatio
)
return
;
for
(
var
i
=
0
;
i
<
this
.
thresholds
.
length
;
i
++
)
{
var
threshold
=
this
.
thresholds
[
i
];
// Return true if an entry matches a threshold or if the new ratio
// and the old ratio are on the opposite sides of a threshold.
if
(
threshold
==
oldRatio
||
threshold
==
newRatio
||
threshold
<
oldRatio
!==
threshold
<
newRatio
)
{
return
true
;
}
}
};
/**
* Returns whether or not the root element is an element and is in the DOM.
* @return {boolean} True if the root element is an element and is in the DOM.
* @private
*/
IntersectionObserver
.
prototype
.
_rootIsInDom
=
function
()
{
return
!
this
.
root
||
containsDeep
(
document
,
this
.
root
);
};
/**
* Returns whether or not the target element is a child of root.
* @param {Element} target The target element to check.
* @return {boolean} True if the target element is a child of root.
* @private
*/
IntersectionObserver
.
prototype
.
_rootContainsTarget
=
function
(
target
)
{
return
containsDeep
(
this
.
root
||
document
,
target
);
};
/**
* Adds the instance to the global IntersectionObserver registry if it isn't
* already present.
* @private
*/
IntersectionObserver
.
prototype
.
_registerInstance
=
function
()
{
if
(
registry
.
indexOf
(
this
)
<
0
)
{
registry
.
push
(
this
);
}
};
/**
* Removes the instance from the global IntersectionObserver registry.
* @private
*/
IntersectionObserver
.
prototype
.
_unregisterInstance
=
function
()
{
var
index
=
registry
.
indexOf
(
this
);
if
(
index
!=
-
1
)
registry
.
splice
(
index
,
1
);
};
/**
* Returns the result of the performance.now() method or null in browsers
* that don't support the API.
* @return {number} The elapsed time since the page was requested.
*/
function
now
()
{
return
window
.
performance
&&
performance
.
now
&&
performance
.
now
();
}
/**
* Throttles a function and delays its executiong, so it's only called at most
* once within a given time period.
* @param {Function} fn The function to throttle.
* @param {number} timeout The amount of time that must pass before the
* function can be called again.
* @return {Function} The throttled function.
*/
function
throttle
(
fn
,
timeout
)
{
var
timer
=
null
;
return
function
()
{
if
(
!
timer
)
{
timer
=
setTimeout
(
function
()
{
fn
();
timer
=
null
;
},
timeout
);
}
};
}
/**
* Adds an event handler to a DOM node ensuring cross-browser compatibility.
* @param {Node} node The DOM node to add the event handler to.
* @param {string} event The event name.
* @param {Function} fn The event handler to add.
* @param {boolean} opt_useCapture Optionally adds the even to the capture
* phase. Note: this only works in modern browsers.
*/
function
addEvent
(
node
,
event
,
fn
,
opt_useCapture
)
{
if
(
typeof
node
.
addEventListener
==
'
function
'
)
{
node
.
addEventListener
(
event
,
fn
,
opt_useCapture
||
false
);
}
else
if
(
typeof
node
.
attachEvent
==
'
function
'
)
{
node
.
attachEvent
(
'
on
'
+
event
,
fn
);
}
}
/**
* Removes a previously added event handler from a DOM node.
* @param {Node} node The DOM node to remove the event handler from.
* @param {string} event The event name.
* @param {Function} fn The event handler to remove.
* @param {boolean} opt_useCapture If the event handler was added with this
* flag set to true, it should be set to true here in order to remove it.
*/
function
removeEvent
(
node
,
event
,
fn
,
opt_useCapture
)
{
if
(
typeof
node
.
removeEventListener
==
'
function
'
)
{
node
.
removeEventListener
(
event
,
fn
,
opt_useCapture
||
false
);
}
else
if
(
typeof
node
.
detatchEvent
==
'
function
'
)
{
node
.
detatchEvent
(
'
on
'
+
event
,
fn
);
}
}
/**
* Returns the intersection between two rect objects.
* @param {Object} rect1 The first rect.
* @param {Object} rect2 The second rect.
* @return {?Object} The intersection rect or undefined if no intersection
* is found.
*/
function
computeRectIntersection
(
rect1
,
rect2
)
{
var
top
=
Math
.
max
(
rect1
.
top
,
rect2
.
top
);
var
bottom
=
Math
.
min
(
rect1
.
bottom
,
rect2
.
bottom
);
var
left
=
Math
.
max
(
rect1
.
left
,
rect2
.
left
);
var
right
=
Math
.
min
(
rect1
.
right
,
rect2
.
right
);
var
width
=
right
-
left
;
var
height
=
bottom
-
top
;
return
(
width
>=
0
&&
height
>=
0
)
&&
{
top
:
top
,
bottom
:
bottom
,
left
:
left
,
right
:
right
,
width
:
width
,
height
:
height
};
}
/**
* Shims the native getBoundingClientRect for compatibility with older IE.
* @param {Element} el The element whose bounding rect to get.
* @return {Object} The (possibly shimmed) rect of the element.
*/
function
getBoundingClientRect
(
el
)
{
var
rect
;
try
{
rect
=
el
.
getBoundingClientRect
();
}
catch
(
err
)
{
// Ignore Windows 7 IE11 "Unspecified error"
// https://github.com/w3c/IntersectionObserver/pull/205
}
if
(
!
rect
)
return
getEmptyRect
();
// Older IE
if
(
!
(
rect
.
width
&&
rect
.
height
))
{
rect
=
{
top
:
rect
.
top
,
right
:
rect
.
right
,
bottom
:
rect
.
bottom
,
left
:
rect
.
left
,
width
:
rect
.
right
-
rect
.
left
,
height
:
rect
.
bottom
-
rect
.
top
};
}
return
rect
;
}
/**
* Returns an empty rect object. An empty rect is returned when an element
* is not in the DOM.
* @return {Object} The empty rect.
*/
function
getEmptyRect
()
{
return
{
top
:
0
,
bottom
:
0
,
left
:
0
,
right
:
0
,
width
:
0
,
height
:
0
};
}
/**
* Checks to see if a parent element contains a child elemnt (including inside
* shadow DOM).
* @param {Node} parent The parent element.
* @param {Node} child The child element.
* @return {boolean} True if the parent node contains the child node.
*/
function
containsDeep
(
parent
,
child
)
{
var
node
=
child
;
while
(
node
)
{
if
(
node
==
parent
)
return
true
;
node
=
getParentNode
(
node
);
}
return
false
;
}
/**
* Gets the parent node of an element or its host element if the parent node
* is a shadow root.
* @param {Node} node The node whose parent to get.
* @return {Node|null} The parent node or null if no parent exists.
*/
function
getParentNode
(
node
)
{
var
parent
=
node
.
parentNode
;
if
(
parent
&&
parent
.
nodeType
==
11
&&
parent
.
host
)
{
// If the parent is a shadow root, return the host element.
return
parent
.
host
;
}
return
parent
;
}
// Exposes the constructors globally.
window
.
IntersectionObserver
=
IntersectionObserver
;
window
.
IntersectionObserverEntry
=
IntersectionObserverEntry
;
}(
window
,
document
));
\ No newline at end of file
This diff is collapsed.
Click to expand it.
index.html
+
2
−
2
View file @
0649a840
<!DOCTYPE html>
<html
lang=
"en"
><head><meta
charset=
"utf-8"
><title>
QuasselDroid
</title><meta
name=
"description"
><link
rel=
"canonical
"
><link
rel=
"shortcut icon"
href=
"favicon.png"
><link
rel=
"shortcut icon"
href=
"favicon.svg"
><meta
property=
"og:site_name"
content=
"QuasselDroid"
><meta
property=
"og:type"
content=
"website"
><meta
property=
"og:title"
content=
"QuasselDroid"
><meta
property=
"og:description"
><meta
property=
"og:url"
><meta
property=
"og:image
"
><meta
property=
"twitter:card"
content=
"summary_large_image"
><meta
property=
"twitter:title"
content=
"QuasselDroid"
><meta
property=
"twitter:description"
><meta
property=
"twitter:url"
><meta
property=
"twitter:image:src
"
><meta
name=
"generator"
content=
"Human v1.0"
><meta
name=
"referrer"
content=
"origin"
><meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
><meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
><meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
><meta
name=
"HandheldFriendly"
content=
"True"
><meta
name=
"theme-color"
content=
"#0a70c0"
><meta
name=
"msapplication-navbutton-color"
content=
"#0a70c0"
><meta
name=
"apple-mobile-web-app-status-bar-style"
content=
"#0a70c0"
><link
rel=
"stylesheet"
href=
"assets/css/semantic.css"
><link
rel=
"stylesheet"
href=
"assets/css/fonts.css"
><link
rel=
"stylesheet"
href=
"assets/css/style.css"
></head><body
class=
"noscript"
id=
"page-index"
><div
class=
"pusher"
><div
class=
"full height"
><div
class=
"following bar"
><div
class=
"ui container"
><div
class=
"ui large secondary menu inverted"
><a
class=
"view-ui item active"
><img
class=
"ui logo left"
src=
"assets/images/icon.svg"
>
QuasselDroid
</a><a
class=
"view-ui item"
href=
"blog/"
>
Blog
</a><div
class=
"right menu"
><a
class=
"view-ui item"
href=
"https://github.com/sandsmark/QuasselDroid"
><i
class=
"icon github left"
></i><span
class=
"text"
>
GitHub
</span></a><a
class=
"view-ui item"
href=
"releases/"
><i
class=
"icon download left"
></i><span
class=
"text"
>
Download
</span></a></div></div></div></div><div
class=
"masthead segment"
><div
class=
"ui container"
><div
class=
"introduction"
><h1
class=
"ui inverted header"
>
QuasselDroid
</h1><h2
class=
"ui inverted"
>
Chat comfortably, everywhere.
</h2><div
class=
"ui hidden divider"
></div><a
class=
"ui huge inverted download button"
href=
"releases/"
><i
class=
"icon download left"
></i><span
class=
"text"
>
Download
</span></a><a
class=
"ui huge inverted basic button"
href=
"https://github.com/sandsmark/QuasselDroid"
><i
class=
"icon github left"
></i><span
class=
"text"
>
GitHub
</span></a></div><div
class=
"row"
><div
class=
"wide column"
><div
id=
"image_container"
><img
class=
"phone"
src=
"assets/images/phone@400.png"
sizes=
"(max-height: 800px) calc(50vw + 101px), (max-width: 800px) calc(50vw + 101px), calc(33vw + 1px)"
srcset=
"assets/images/phone@220.png 220w, assets/images/phone@300.png 300w, assets/images/phone@400.png 400w, assets/images/phone@520.png 520w, assets/images/phone@640.png 640w, assets/images/phone@800.png 800w, assets/images/phone@1000.png 1000w, assets/images/phone@1220.png 1220w"
><noscript><img
class=
"tablet"
src=
"assets/images/tablet@1090.png"
sizes=
"calc(33vw + 1px)"
srcset=
"assets/images/tablet@545.png 545w, assets/images/tablet@640.png 640w, assets/images/tablet@720.png 720w, assets/images/tablet@800.png 800w, assets/images/tablet@880.png 880w, assets/images/tablet@960.png 960w, assets/images/tablet@1090.png 1090w, assets/images/tablet@thumb35.png 1635w, assets/images/tablet@2180.png 2180w"
></noscript><img
class=
"tablet"
src=
"assets/images/tablet@thumb.jpg"
data-src=
"assets/images/tablet@1090.png"
sizes=
"calc(33vw + 1px)"
data-srcset=
"assets/images/tablet@545.png 545w, assets/images/tablet@640.png 640w, assets/images/tablet@720.png 720w, assets/images/tablet@800.png 800w, assets/images/tablet@880.png 880w, assets/images/tablet@960.png 960w, assets/images/tablet@1090.png 1090w, assets/images/tablet@thumb35.png 1635w, assets/images/tablet@2180.png 2180w"
></div></div></div></div></div><div
class=
"ui vertical stripe intro segment"
><div
class=
"ui stackable very relaxed center aligned grid container"
><div
class=
"row"
><div
class=
"seven wide column left aligned"
><h2
class=
"ui header"
>
Built on Quassel
</h2><p>
Quassel makes IRC fun again – open a client anywhere, connect
<!DOCTYPE html>
<html
lang=
"en"
><head><meta
charset=
"utf-8"
><title>
QuasselDroid
</title><meta
name=
"description"
content=
"Chat comfortably, everywhere."
><link
rel=
"canonical"
href=
"https://quasseldroid.info/
"
><link
rel=
"shortcut icon"
href=
"favicon.png"
><link
rel=
"shortcut icon"
href=
"favicon.svg"
><meta
property=
"og:site_name"
content=
"QuasselDroid"
><meta
property=
"og:type"
content=
"website"
><meta
property=
"og:title"
content=
"QuasselDroid"
><meta
property=
"og:description"
content=
"Chat comfortably, everywhere."
><meta
property=
"og:url"
content=
"https://quasseldroid.info/
"
><meta
property=
"twitter:card"
content=
"summary_large_image"
><meta
property=
"twitter:title"
content=
"QuasselDroid"
><meta
property=
"twitter:description"
content=
"Chat comfortably, everywhere."
><meta
property=
"twitter:url"
content=
"https://quasseldroid.info/
"
><meta
name=
"generator"
content=
"Human v1.0"
><meta
name=
"referrer"
content=
"origin"
><meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
><meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
><meta
name=
"apple-mobile-web-app-capable"
content=
"yes"
><meta
name=
"HandheldFriendly"
content=
"True"
><meta
name=
"theme-color"
content=
"#0a70c0"
><meta
name=
"msapplication-navbutton-color"
content=
"#0a70c0"
><meta
name=
"apple-mobile-web-app-status-bar-style"
content=
"#0a70c0"
><link
rel=
"stylesheet"
href=
"assets/css/semantic.css"
><link
rel=
"stylesheet"
href=
"assets/css/fonts.css"
><link
rel=
"stylesheet"
href=
"assets/css/style.css"
></head><body
class=
"noscript"
id=
"page-index"
><div
class=
"pusher"
><div
class=
"full height"
><div
class=
"following bar"
><div
class=
"ui container"
><div
class=
"ui large secondary menu inverted"
><a
class=
"view-ui item active"
><img
class=
"ui logo left"
src=
"assets/images/icon.svg"
>
QuasselDroid
</a><a
class=
"view-ui item"
href=
"blog/"
>
Blog
</a><div
class=
"right menu"
><a
class=
"view-ui item"
href=
"https://github.com/sandsmark/QuasselDroid"
><i
class=
"icon github left"
></i><span
class=
"text"
>
GitHub
</span></a><a
class=
"view-ui item"
href=
"releases/"
><i
class=
"icon download left"
></i><span
class=
"text"
>
Download
</span></a></div></div></div></div><div
class=
"masthead segment"
><div
class=
"ui container"
><div
class=
"introduction"
><h1
class=
"ui inverted header"
>
QuasselDroid
</h1><h2
class=
"ui inverted"
>
Chat comfortably, everywhere.
</h2><div
class=
"ui hidden divider"
></div><a
class=
"ui huge inverted download button"
href=
"releases/"
><i
class=
"icon download left"
></i><span
class=
"text"
>
Download
</span></a><a
class=
"ui huge inverted basic button"
href=
"https://github.com/sandsmark/QuasselDroid"
><i
class=
"icon github left"
></i><span
class=
"text"
>
GitHub
</span></a></div><div
class=
"row"
><div
class=
"wide column"
><div
id=
"image_container"
><img
class=
"phone"
src=
"assets/images/phone@400.png"
sizes=
"(max-height: 800px) calc(50vw + 101px), (max-width: 800px) calc(50vw + 101px), calc(33vw + 1px)"
srcset=
"assets/images/phone@220.png 220w, assets/images/phone@300.png 300w, assets/images/phone@400.png 400w, assets/images/phone@520.png 520w, assets/images/phone@640.png 640w, assets/images/phone@800.png 800w, assets/images/phone@1000.png 1000w, assets/images/phone@1220.png 1220w"
><noscript><img
class=
"tablet"
src=
"assets/images/tablet@1090.png"
sizes=
"calc(33vw + 1px)"
srcset=
"assets/images/tablet@545.png 545w, assets/images/tablet@640.png 640w, assets/images/tablet@720.png 720w, assets/images/tablet@800.png 800w, assets/images/tablet@880.png 880w, assets/images/tablet@960.png 960w, assets/images/tablet@1090.png 1090w, assets/images/tablet@thumb35.png 1635w, assets/images/tablet@2180.png 2180w"
></noscript><img
class=
"tablet"
src=
"assets/images/tablet@thumb.jpg"
data-src=
"assets/images/tablet@1090.png"
sizes=
"calc(33vw + 1px)"
data-srcset=
"assets/images/tablet@545.png 545w, assets/images/tablet@640.png 640w, assets/images/tablet@720.png 720w, assets/images/tablet@800.png 800w, assets/images/tablet@880.png 880w, assets/images/tablet@960.png 960w, assets/images/tablet@1090.png 1090w, assets/images/tablet@thumb35.png 1635w, assets/images/tablet@2180.png 2180w"
></div></div></div></div></div><div
class=
"ui vertical stripe intro segment"
><div
class=
"ui stackable very relaxed center aligned grid container"
><div
class=
"row"
><div
class=
"seven wide column left aligned"
><h2
class=
"ui header"
>
Built on Quassel
</h2><p>
Quassel makes IRC fun again – open a client anywhere, connect
to your core, and have all your favourite channels and
to your core, and have all your favourite channels and
networks right there.
</p><p>
Be it at home with Windows, macOS, Linux, on the go with
networks right there.
</p><p>
Be it at home with Windows, macOS, Linux, on the go with
Android or iOS, or via the web. Everything is exactly the way
Android or iOS, or via the web. Everything is exactly the way
...
@@ -9,4 +9,4 @@ little bit of the UI to your liking, you can truly
...
@@ -9,4 +9,4 @@ little bit of the UI to your liking, you can truly
customize QuasselDroid however you’d like.
</p><p>
Special themes for every situation – be it AMOLED displays
customize QuasselDroid however you’d like.
</p><p>
Special themes for every situation – be it AMOLED displays
or holidays – are available, and improve your battery life
or holidays – are available, and improve your battery life
or just look fancy.
</p></div><div
class=
"nine wide column"
><div
class=
"ui one doubling cards"
><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/themes@1180.png 1180w"
sizes=
"(max-width: 767px) calc(100vw + 1px), (max-width: 991px) 364px, (max-width: 1199px) 475px, 591px"
srcset=
"assets/images/themes@363.png 363w, assets/images/themes@474.png 474w, assets/images/themes@590.png 590w, assets/images/themes@726.png 726w, assets/images/themes@948.png 948w, assets/images/themes@1180.png 1180w"
></noscript><img
data-src=
"assets/images/themes@1180.png 1180w"
sizes=
"(max-width: 767px) calc(100vw + 1px), (max-width: 991px) 364px, (max-width: 1199px) 475px, 591px"
data-srcset=
"assets/images/themes@363.png 363w, assets/images/themes@474.png 474w, assets/images/themes@590.png 590w, assets/images/themes@726.png 726w, assets/images/themes@948.png 948w, assets/images/themes@1180.png 1180w"
></div></div></div></div></div><div
class=
"ui divider"
></div><div
class=
"row centered"
><div
class=
"wide column"
><div
class=
"ui four doubling cards"
><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/quassel_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/quassel_dark@220.png 220w, assets/images/quassel_dark@266.png 266w, assets/images/quassel_dark@335.png 335w, assets/images/quassel_dark@352.png 352w, assets/images/quassel_dark@532.png 532w"
></noscript><img
src=
"assets/images/quassel_dark@thumb.jpg"
data-src=
"assets/images/quassel_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/quassel_dark@220.png 220w, assets/images/quassel_dark@266.png 266w, assets/images/quassel_dark@335.png 335w, assets/images/quassel_dark@352.png 352w, assets/images/quassel_dark@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Quassel Dark
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/quassel_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/quassel_light@220.png 220w, assets/images/quassel_light@266.png 266w, assets/images/quassel_light@335.png 335w, assets/images/quassel_light@352.png 352w, assets/images/quassel_light@532.png 532w"
></noscript><img
src=
"assets/images/quassel_light@thumb.jpg"
data-src=
"assets/images/quassel_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/quassel_light@220.png 220w, assets/images/quassel_light@266.png 266w, assets/images/quassel_light@335.png 335w, assets/images/quassel_light@352.png 352w, assets/images/quassel_light@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Quassel Light
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/solarized_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/solarized_dark@220.png 220w, assets/images/solarized_dark@266.png 266w, assets/images/solarized_dark@335.png 335w, assets/images/solarized_dark@352.png 352w, assets/images/solarized_dark@532.png 532w"
></noscript><img
src=
"assets/images/solarized_dark@thumb.jpg"
data-src=
"assets/images/solarized_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/solarized_dark@220.png 220w, assets/images/solarized_dark@266.png 266w, assets/images/solarized_dark@335.png 335w, assets/images/solarized_dark@352.png 352w, assets/images/solarized_dark@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Solarized Dark
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/solarized_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/solarized_light@220.png 220w, assets/images/solarized_light@266.png 266w, assets/images/solarized_light@335.png 335w, assets/images/solarized_light@352.png 352w, assets/images/solarized_light@532.png 532w"
></noscript><img
src=
"assets/images/solarized_light@thumb.jpg"
data-src=
"assets/images/solarized_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/solarized_light@220.png 220w, assets/images/solarized_light@266.png 266w, assets/images/solarized_light@335.png 335w, assets/images/solarized_light@352.png 352w, assets/images/solarized_light@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Solarized Light
</div></div></div></div></div></div></div></div></div><div
class=
"ui black inverted vertical footer segment"
><div
class=
"ui center aligned container"
><div
class=
"ui stackable inverted grid"
><div
class=
"three wide column"
><h4
class=
"ui inverted header"
>
Community
</h4><div
class=
"ui inverted link list"
><a
class=
"item"
href=
"https://www.transifex.com/quasseldroid/quasseldroid/"
>
Help Translate
</a><a
class=
"item"
href=
"https://github.com/sandsmark/quasseldroid/issues/"
>
Submit an Issue
</a><a
class=
"item"
href=
"irc://chat.freenode.org/#quasseldroid"
>
Join our Chat
</a><a
class=
"item"
href=
"/beta/"
>
Beta Releases
</a></div></div><div
class=
"three wide column"
><h4
class=
"ui inverted header"
>
Discover More
</h4><div
class=
"ui inverted link list"
><a
class=
"item"
href=
"http://quassel-irc.org/"
>
Quassel
</a><a
class=
"item"
href=
"https://github.com/magne4000/quassel-webserver/"
>
quassel-webserver
</a><a
class=
"item"
href=
"https://github.com/phhusson/quassel-irssi"
>
quassel-irssi
</a><a
class=
"item"
href=
"https://woboq.com/iquassel.html"
>
iQuassel
</a></div></div></div><div
class=
"ui inverted section divider"
></div><img
class=
"ui centered mini image"
src=
"assets/images/icon.svg"
><div
class=
"ui horizontal inverted small divided link list"
><a
class=
"item"
href=
"https://github.com/sandsmark/QuasselDroid"
>
Free
&
Open Source
or just look fancy.
</p></div><div
class=
"nine wide column"
><div
class=
"ui one doubling cards"
><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/themes@1180.png 1180w"
sizes=
"(max-width: 767px) calc(100vw + 1px), (max-width: 991px) 364px, (max-width: 1199px) 475px, 591px"
srcset=
"assets/images/themes@363.png 363w, assets/images/themes@474.png 474w, assets/images/themes@590.png 590w, assets/images/themes@726.png 726w, assets/images/themes@948.png 948w, assets/images/themes@1180.png 1180w"
></noscript><img
data-src=
"assets/images/themes@1180.png 1180w"
sizes=
"(max-width: 767px) calc(100vw + 1px), (max-width: 991px) 364px, (max-width: 1199px) 475px, 591px"
data-srcset=
"assets/images/themes@363.png 363w, assets/images/themes@474.png 474w, assets/images/themes@590.png 590w, assets/images/themes@726.png 726w, assets/images/themes@948.png 948w, assets/images/themes@1180.png 1180w"
></div></div></div></div></div><div
class=
"ui divider"
></div><div
class=
"row centered"
><div
class=
"wide column"
><div
class=
"ui four doubling cards"
><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/quassel_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/quassel_dark@220.png 220w, assets/images/quassel_dark@266.png 266w, assets/images/quassel_dark@335.png 335w, assets/images/quassel_dark@352.png 352w, assets/images/quassel_dark@532.png 532w"
></noscript><img
src=
"assets/images/quassel_dark@thumb.jpg"
data-src=
"assets/images/quassel_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/quassel_dark@220.png 220w, assets/images/quassel_dark@266.png 266w, assets/images/quassel_dark@335.png 335w, assets/images/quassel_dark@352.png 352w, assets/images/quassel_dark@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Quassel Dark
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/quassel_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/quassel_light@220.png 220w, assets/images/quassel_light@266.png 266w, assets/images/quassel_light@335.png 335w, assets/images/quassel_light@352.png 352w, assets/images/quassel_light@532.png 532w"
></noscript><img
src=
"assets/images/quassel_light@thumb.jpg"
data-src=
"assets/images/quassel_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/quassel_light@220.png 220w, assets/images/quassel_light@266.png 266w, assets/images/quassel_light@335.png 335w, assets/images/quassel_light@352.png 352w, assets/images/quassel_light@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Quassel Light
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/solarized_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/solarized_dark@220.png 220w, assets/images/solarized_dark@266.png 266w, assets/images/solarized_dark@335.png 335w, assets/images/solarized_dark@352.png 352w, assets/images/solarized_dark@532.png 532w"
></noscript><img
src=
"assets/images/solarized_dark@thumb.jpg"
data-src=
"assets/images/solarized_dark@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/solarized_dark@220.png 220w, assets/images/solarized_dark@266.png 266w, assets/images/solarized_dark@335.png 335w, assets/images/solarized_dark@352.png 352w, assets/images/solarized_dark@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Solarized Dark
</div></div></div><div
class=
"card"
><div
class=
"image"
><noscript><img
src=
"assets/images/solarized_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
srcset=
"assets/images/solarized_light@220.png 220w, assets/images/solarized_light@266.png 266w, assets/images/solarized_light@335.png 335w, assets/images/solarized_light@352.png 352w, assets/images/solarized_light@532.png 532w"
></noscript><img
src=
"assets/images/solarized_light@thumb.jpg"
data-src=
"assets/images/solarized_light@266.png"
sizes=
"(max-width: 767px) calc(50vw - 2em + 1px), (max-width: 991px) 336px, (max-width: 1199px) 221px, 267px"
data-srcset=
"assets/images/solarized_light@220.png 220w, assets/images/solarized_light@266.png 266w, assets/images/solarized_light@335.png 335w, assets/images/solarized_light@352.png 352w, assets/images/solarized_light@532.png 532w"
></div><div
class=
"content"
><div
class=
"extra"
>
Solarized Light
</div></div></div></div></div></div></div></div></div><div
class=
"ui black inverted vertical footer segment"
><div
class=
"ui center aligned container"
><div
class=
"ui stackable inverted grid"
><div
class=
"three wide column"
><h4
class=
"ui inverted header"
>
Community
</h4><div
class=
"ui inverted link list"
><a
class=
"item"
href=
"https://www.transifex.com/quasseldroid/quasseldroid/"
>
Help Translate
</a><a
class=
"item"
href=
"https://github.com/sandsmark/quasseldroid/issues/"
>
Submit an Issue
</a><a
class=
"item"
href=
"irc://chat.freenode.org/#quasseldroid"
>
Join our Chat
</a><a
class=
"item"
href=
"/beta/"
>
Beta Releases
</a></div></div><div
class=
"three wide column"
><h4
class=
"ui inverted header"
>
Discover More
</h4><div
class=
"ui inverted link list"
><a
class=
"item"
href=
"http://quassel-irc.org/"
>
Quassel
</a><a
class=
"item"
href=
"https://github.com/magne4000/quassel-webserver/"
>
quassel-webserver
</a><a
class=
"item"
href=
"https://github.com/phhusson/quassel-irssi"
>
quassel-irssi
</a><a
class=
"item"
href=
"https://woboq.com/iquassel.html"
>
iQuassel
</a></div></div></div><div
class=
"ui inverted section divider"
></div><img
class=
"ui centered mini image"
src=
"assets/images/icon.svg"
><div
class=
"ui horizontal inverted small divided link list"
><a
class=
"item"
href=
"https://github.com/sandsmark/QuasselDroid"
>
Free
&
Open Source
</a></div></div></div></div><script
src=
"assets/js/script.js"
></script></body></html>
</a></div></div></div></div><script
src=
"assets/js/intersectionobserver.js"
></script><script
src=
"assets/js/script.js"
></script></body></html>
\ No newline at end of file
\ No newline at end of file
This diff is collapsed.
Click to expand it.
index.pug
+
4
−
2
View file @
0649a840
- var pageDescription = "Chat comfortably, everywhere.";
- var pageUrl = "https://quasseldroid.info/";
doctype html
doctype html
html(lang="en")
html(lang="en")
head
head
...
@@ -14,13 +17,11 @@ html(lang="en")
...
@@ -14,13 +17,11 @@ html(lang="en")
meta(property="og:title" content="QuasselDroid")
meta(property="og:title" content="QuasselDroid")
meta(property="og:description" content=pageDescription)
meta(property="og:description" content=pageDescription)
meta(property="og:url" content=pageUrl)
meta(property="og:url" content=pageUrl)
meta(property="og:image" content=pageThumb)
meta(property="twitter:card" content="summary_large_image")
meta(property="twitter:card" content="summary_large_image")
meta(property="twitter:title" content="QuasselDroid")
meta(property="twitter:title" content="QuasselDroid")
meta(property="twitter:description" content=pageDescription)
meta(property="twitter:description" content=pageDescription)
meta(property="twitter:url" content=pageUrl)
meta(property="twitter:url" content=pageUrl)
meta(property="twitter:image:src" content=pageThumb)
meta(name="generator" content="Human v1.0")
meta(name="generator" content="Human v1.0")
...
@@ -213,4 +214,5 @@ html(lang="en")
...
@@ -213,4 +214,5 @@ html(lang="en")
a.item(href="https://github.com/sandsmark/QuasselDroid").
a.item(href="https://github.com/sandsmark/QuasselDroid").
Free & Open Source
Free & Open Source
script(src="assets/js/intersectionobserver.js")
script(src="assets/js/script.js")
script(src="assets/js/script.js")
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment