<?php
class GistEdit {
private $data;
private static $_instance = NULL ;
public static function init () {
if (self::$_instance === NULL) {
self::$_instance = new self;
}
self::$_instance->data = array();
return self::$_instance;
}
public function edit ($file, $newContent = NULL, $newFileName = NULL) {
if ($newContent !== NULL) {
$this->data[$file]['content'] = $newContent ;
}
if ($newFileName !== NULL) {
$this->data[$file]['filename'] = $newFileName ;
}
return $this;
}
public function deleteFile ($file) {
$this->data[$file] = NULL ;
return $this;
}
public function newFile ($file, $content){
$this->data[$file]['content'] = $content;
return $this;
}
public function get () {
return $this->data;
}
}
class gistAPI {
private $url = "https://api.github.com" ;
private $user = "github" ;
public $ch ;
private $response ;
public $loginInfo ;
function __construct($id = NULL, $pass = NULL) {
if($id === NULL || $pass === NULL){
$loginInfo = NULL;
} else {
$loginInfo = array('username' => $id,
'password' => $pass);
}
$this->loginInfo = $loginInfo;
$this->chReset();
}
public function listGists ($type = "public", $user = NULL) {
switch ($type) {
case "public":
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/public");
break;
case "user":
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/users/" . ($user === NULL ? $this->user:$user) ."/gists");
break;
case "starred":
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/starred");
break;
}
return $this->returnCode();
}
public function getGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/".$gistId);
return $this->returnCode();
}
public function createGist ($files, $description = "", $public = false) {
$filesArray = array();
foreach ($files as $fileName => $content)
$filesArray[$fileName]['content'] = $content;
$postArray = array(
"files" => $filesArray,
"description" => $description,
"public" => $public
);
$jsonArray = json_encode($postArray);
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists");
curl_setopt($this->ch, CURLOPT_POST, 1);
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $jsonArray);
return $this->returnCode();
}
public function editGist ($gistId, $files = NULL, $description = NULL) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
if ($files === NULL && $description !== NULL) {
$jsonArray = json_encode(array("description" => $description));
} elseif ($description === NULL && $files !== NULL) {
$jsonArray = json_encode(array("files" => $files));
} elseif ($description !== NULL && $files !== NULL) {
$jsonArray = json_encode(array("description" => $description, "files" => $files));
} else {
$this->chReset();
return 0;
}
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $jsonArray);
return $this->returnCode();
}
public function gistCommits ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/" . $gistId . "/commits");
return $this->returnCode();
}
public function starGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/star");
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'PUT');
return $this->returnCode();
}
public function unstarGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/star");
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
return $this->returnCode();
}
public function checkStarGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/star");
return $this->returnCode();
}
public function forkGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/forks");
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'POST');
return $this->returnCode();
}
public function listForkGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/forks");
return $this->returnCode();
}
public function deleteGist ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
return $this->returnCode();
}
public function gistComments ($gistId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/".$gistId."/comments");
return $this->returnCode();
}
public function getComment ($gistId, $commentId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/comments/". $commentId);
return $this->returnCode();
}
public function createComment ($gistId, $comment){
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/comments");
curl_setopt($this->ch, CURLOPT_POST, 1);
$jsonArray = json_encode(array("body" => $comment));
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $jsonArray);
return $this->returnCode();
}
public function editComment ($gistId, $commentId, $comment) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/comments/". $commentId);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
$jsonArray = json_encode(array("body" => $comment));
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $jsonArray);
return $this->returnCode();
}
public function deleteComment ($gistId, $commentId) {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/gists/". $gistId ."/comments/". $commentId);
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
return $this->returnCode();
}
public function getLimits() {
curl_setopt($this->ch, CURLOPT_URL, $this->url . "/rate_limit");
return $this->returnCode();
}
private function parseHeader ($header_text) {
$headers = array();
foreach (explode("\r\n", $header_text) as $i => $line){
if (strlen($line) > 1 && $i != 0){
list ($key, $value) = explode(': ', $line);
$headers[$key] = $value;
} else if ($i == 0){
$headers['http_code'] = $line;
}
}
return $headers;
}
private function returnCode () {
$this->response = curl_exec($this->ch);
$header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
$header = substr($this->response, 0, $header_size);
$body = substr($this->response, $header_size);
$return = array("header" => $this->parseHeader($header),
"body" => json_decode($body, true),
"raw" => $this->response);
$this->chReset();
return $return;
}
public function chReset () {
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_HEADER, true);
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_TIMEOUT, 30);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
if ($this->loginInfo !== NULL){
$this->user = $this->loginInfo['username'];
curl_setopt($this->ch, CURLOPT_USERAGENT, $this->loginInfo['username']);
curl_setopt($this->ch, CURLOPT_USERPWD, $this->loginInfo['username'].":".$this->loginInfo['password']);
} else {
curl_setopt($this->ch, CURLOPT_USERAGENT, "gistAPI v1.0");
}
unset($this->response);
}
function __destruct() {
curl_close($this->ch);
}
}
?>
<?php
class Fruit {
private $color = "red";
public function getColor() {
return $this->color;
}
public function &getColorByRef() {
return $this->color;
}
}
echo "\nTEST RUN 1:\n\n";
$fruit = new Fruit;
$color = $fruit->getColor();
echo "Fruit's color is $color\n";
$color = "green"; // does nothing, but bear with me
$color = $fruit->getColor();
echo "Fruit's color is $color\n";
echo "\nTEST RUN 2:\n\n";
$fruit = new Fruit;
$color = &$fruit->getColorByRef(); // also need to put & here
echo "Fruit's color is $color\n";
$color = "green"; // now this changes the actual property of $fruit
$x = $fruit->getColor();
echo "Fruit's color is $color\n";
<?php
/**
* This file is part of Tree
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Nicolò Martini <nicmartnic@gmail.com>
*/
namespace Tree\Node;
use Tree\Visitor\Visitor;
trait NodeTrait
{
/**
* @var mixed
*/
private $value;
/**
* parent
*
* @var NodeInterface
* @access private
*/
private $parent;
/**
* @var NodeInterface[]
*/
private $children = [];
/**
* @param mixed $value
* @param NodeInterface[] $children
*/
public function __construct($value = null, array $children = [])
{
$this->setValue($value);
if (!empty($children)) {
$this->setChildren($children);
}
}
/**
* {@inheritdoc}
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* {@inheritdoc}
*/
public function getValue()
{
return $this->value;
}
/**
* {@inheritdoc}
*/
public function addChild(NodeInterface $child)
{
$child->setParent($this);
$this->children[] = $child;
return $this;
}
/**
* {@inheritdoc}
*/
public function removeChild(NodeInterface $child)
{
foreach ($this->children as $key => $myChild) {
if ($child == $myChild) {
unset($this->children[$key]);
}
}
$this->children = array_values($this->children);
$child->setParent(null);
return $this;
}
/**
* {@inheritdoc}
*/
public function removeAllChildren()
{
$this->setChildren([]);
return $this;
}
/**
* {@inheritdoc}
*/
public function getChildren()
{
return $this->children;
}
/**
* {@inheritdoc}
*/
public function setChildren(array $children)
{
$this->removeParentFromChildren();
$this->children = [];
foreach ($children as $child) {
$this->addChild($child);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function setParent(NodeInterface $parent = null)
{
$this->parent = $parent;
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return $this->parent;
}
/**
* {@inheritdoc}
*/
public function getAncestors()
{
$parents = [];
$node = $this;
while ($parent = $node->getParent()) {
array_unshift($parents, $parent);
$node = $parent;
}
return $parents;
}
/**
* {@inheritDoc}
*/
public function getAncestorsAndSelf()
{
return array_merge($this->getAncestors(), [$this]);
}
/**
* {@inheritdoc}
*/
public function getNeighbors()
{
$neighbors = $this->getParent()->getChildren();
$current = $this;
// Uses array_values to reset indexes after filter.
return array_values(
array_filter(
$neighbors,
function ($item) use ($current) {
return $item != $current;
}
)
);
}
/**
* {@inheritDoc}
*/
public function getNeighborsAndSelf()
{
return $this->getParent()->getChildren();
}
/**
* {@inheritDoc}
*/
public function isLeaf()
{
return count($this->children) === 0;
}
/**
* @return bool
*/
public function isRoot()
{
return $this->getParent() === null;
}
/**
* {@inheritDoc}
*/
public function isChild()
{
return $this->getParent() !== null;
}
/**
* Find the root of the node
*
* @return NodeInterface
*/
public function root()
{
$node = $this;
while ($parent = $node->getParent())
$node = $parent;
return $node;
}
/**
* Return the distance from the current node to the root.
*
* Warning, can be expensive, since each descendant is visited
*
* @return int
*/
public function getDepth()
{
if ($this->isRoot()) {
return 0;
}
return $this->getParent()->getDepth() + 1;
}
/**
* Return the height of the tree whose root is this node
*
* @return int
*/
public function getHeight()
{
if ($this->isLeaf()) {
return 0;
}
$heights = [];
foreach ($this->getChildren() as $child) {
$heights[] = $child->getHeight();
}
return max($heights) + 1;
}
/**
* Return the number of nodes in a tree
* @return int
*/
public function getSize()
{
$size = 1;
foreach ($this->getChildren() as $child) {
$size += $child->getSize();
}
return $size;
}
/**
* {@inheritdoc}
*/
public function accept(Visitor $visitor)
{
return $visitor->visit($this);
}
private function removeParentFromChildren()
{
foreach ($this->getChildren() as $child)
$child->setParent(null);
}
}
(function ($) {
$.fn.slideShow = function (options) {
// Supplying default options
options = $.extend({
timeOut: 3000,
showNavigation: true,
pauseOnHover: true,
swipeNavigation: true
}, options);
// Variables
var intervals = [],
slideshowImgs = [],
originalSrc,
img,
cont,
width,
height,
// Creates an object with all the elements with a 'data-slideshow' attribute
container = this.filter(function () {
return $(this).data('slideshow');
});
// Cycle through all the elements from the container object
// Later on we'll use the "i" variable to distinguish the separate slideshows from one another
for (var i = 0; i < container.length; i++) {
cont = $(container[i]);
width = container.eq(i).outerWidth(true);
height = container.eq(i).outerHeight(true);
// For every separate slideshow, create a helper <div>, each with its own ID.
// In those we'll store the images for our slides.
var helpdiv = $('<div id="slideshow-container-' + i + '" class="slideshow" >');
helpdiv.height(height);
helpdiv.width(width);
// If this option is enabled, call a function that appends buttons
if (options.showNavigation) {
createNavigation();
}
// Append the original image to the helper <div>
originalSrc = cont.attr('src');
img = $('<div class="slide" style="background-image: url(' + originalSrc + ')">');
img.appendTo(helpdiv);
// Append the images from the data-slideshow attribute
slideshowImgs[i] = cont.attr('data-slideshow').split("|");
for (var j = 0; j < slideshowImgs[i].length; j++) {
img = $('<div class="slide" style="background-image: url(' + slideshowImgs[i][j] + ')">');
img.appendTo(helpdiv);
}
// Replace the original element with the helper <div>
cont.replaceWith(helpdiv);
// Activate the slideshow
automaticSlide(i)
}
// Functions
// Slideshow auto switch
function automaticSlide(index) {
// Hide all the images except the first one
$('#slideshow-container-' + index + ' .slide:gt(0)').hide();
// Every few seconds fade out the first image, fade in the next one,
// then take the first and append it to the container again, where it becomes last
intervals[index] = setInterval(function () {
$('#slideshow-container-' + index + ' .slide:first').fadeOut("slow")
.next('.slide').fadeIn("slow")
.end().appendTo('#slideshow-container-' + index + '');
},
options.timeOut);
}
// Pause on hover and resume on mouse leave
if (options.pauseOnHover) {
(function hoverPause() {
$('.slideshow').on({
'mouseenter.hover': function () {
clearInterval(intervals[($(this).attr('id').split('-')[2])])
},
'mouseleave.hover': function () {
automaticSlide($(this).attr('id').split('-')[2])
}
});
})()
}
// We use this to prevent the slideshow from resuming once we've stopped it
function hoverStop(id) {
$('#' + id + '').off('mouseenter.hover mouseleave.hover');
}
// Create the navigation buttons
function createNavigation() {
// The buttons themselves
var leftArrow = $('<div class="leftBtn slideBtn hide">');
var rightArrow = $('<div class="rightBtn slideBtn hide">');
// Arrows for the buttons
var nextPointer = $('<span class="pointer next"></span>');
var prevPointer = $('<span class="pointer previous"></span>');
prevPointer.appendTo(leftArrow);
nextPointer.appendTo(rightArrow);
leftArrow.appendTo(helpdiv);
rightArrow.appendTo(helpdiv);
}
// Slideshow manual switch
if (options.showNavigation) {
// This shows the navigation when the mouse enters the slideshow
// and hides it again when it leaves it
$('.slideshow').on({
'mouseenter': function () {
$(this).find('.leftBtn, .rightBtn').removeClass('hide')
},
'mouseleave': function () {
$(this).find('.leftBtn, .rightBtn').addClass('hide')
}
});
// Upon click, stop the automatic slideshow and change the slide
$('.leftBtn').on('click', function () {
// Clear the corresponding interval to stop the slideshow
// (intervals is an array, so we give it the number of the slideshow container)
clearInterval(intervals[($(this).parent().attr('id').split('-')[2])]);
// Make the last slide visible and set it as first in the slideshow container
$(this).parent().find('.slide:last').fadeIn("slow")
.insertBefore($(this).parent().find('.slide:first').fadeOut("slow"));
hoverStop($(this).parent().attr('id'));
});
$('.rightBtn').on('click', function () {
// Clear the corresponding interval to stop the slideshow
clearInterval(intervals[($(this).parent().attr('id').split('-')[2])]);
// Fade out the current image and append it to the parent, making it last
// Fade in the next one
$(this).parent().find('.slide:first').fadeOut("slow")
.next('.slide').fadeIn("slow")
.end().appendTo($(this).parent());
hoverStop($(this).parent().attr('id'));
});
}
// Change slide on swipe
// Same as the 'on click' functions, but we use hammer.js this time
if (options.swipeNavigation) {
$('.slideshow').hammer().on({
"swiperight": function () {
clearInterval(intervals[($(this).attr('id').split('-')[2])]);
$(this).find('.slide:last').fadeIn("slow")
.insertBefore($(this).find('.slide:first').fadeOut("slow"))
},
"swipeleft": function () {
clearInterval(intervals[($(this).attr('id').split('-')[2])]);
$(this).find('.slide:first').fadeOut("slow")
.next('.slide').fadeIn("slow")
.end().appendTo($(this));
}
})
}
}
}(jQuery)
)
;
(function($){
$.fn.tzCheckbox = function(options){
// Default On / Off labels:
options = $.extend({
labels : ['ON','OFF']
},options);
return this.each(function(){
var originalCheckBox = $(this),
labels = [];
// Checking for the data-on / data-off HTML5 data attributes:
if(originalCheckBox.data('on')){
labels[0] = originalCheckBox.data('on');
labels[1] = originalCheckBox.data('off');
}
else labels = options.labels;
// Creating the new checkbox markup:
var checkBox = $('<span>',{
className : 'tzCheckBox '+(this.checked?'checked':''),
html: '<span class="tzCBContent">'+labels[this.checked?0:1]+
'</span><span class="tzCBPart"></span>'
});
// Inserting the new checkbox, and hiding the original:
checkBox.insertAfter(originalCheckBox.hide());
checkBox.click(function(){
checkBox.toggleClass('checked');
var isChecked = checkBox.hasClass('checked');
// Synchronizing the original checkbox:
originalCheckBox.attr('checked',isChecked);
checkBox.find('.tzCBContent').html(labels[isChecked?0:1]);
});
// Listening for changes on the original and affecting the new one:
originalCheckBox.bind('change',function(){
checkBox.click();
});
});
};
})(jQuery);
(function($){
$.fn.colorTip = function(settings){
var defaultSettings = {
color : 'yellow',
timeout : 500
}
var supportedColors = ['red','green','blue','white','yellow','black'];
/* Combining the default settings object with the supplied one */
settings = $.extend(defaultSettings,settings);
/*
* Looping through all the elements and returning them afterwards.
* This will add chainability to the plugin.
*/
return this.each(function(){
var elem = $(this);
// If the title attribute is empty, continue with the next element
if(!elem.attr('title')) return true;
// Creating new eventScheduler and Tip objects for this element.
// (See the class definition at the bottom).
var scheduleEvent = new eventScheduler();
var tip = new Tip(elem.attr('title'));
// Adding the tooltip markup to the element and
// applying a special class:
elem.append(tip.generate()).addClass('colorTipContainer');
// Checking to see whether a supported color has been
// set as a classname on the element.
var hasClass = false;
for(var i=0;i<supportedColors.length;i++)
{
if(elem.hasClass(supportedColors[i])){
hasClass = true;
break;
}
}
// If it has been set, it will override the default color
if(!hasClass){
elem.addClass(settings.color);
}
// On mouseenter, show the tip, on mouseleave set the
// tip to be hidden in half a second.
elem.hover(function(){
tip.show();
// If the user moves away and hovers over the tip again,
// clear the previously set event:
scheduleEvent.clear();
},function(){
// Schedule event actualy sets a timeout (as you can
// see from the class definition below).
scheduleEvent.set(function(){
tip.hide();
},settings.timeout);
});
// Removing the title attribute, so the regular OS titles are
// not shown along with the tooltips.
elem.removeAttr('title');
});
}
/*
/ Event Scheduler Class Definition
*/
function eventScheduler(){}
eventScheduler.prototype = {
set : function (func,timeout){
// The set method takes a function and a time period (ms) as
// parameters, and sets a timeout
this.timer = setTimeout(func,timeout);
},
clear: function(){
// The clear method clears the timeout
clearTimeout(this.timer);
}
}
/*
/ Tip Class Definition
*/
function Tip(txt){
this.content = txt;
this.shown = false;
}
Tip.prototype = {
generate: function(){
// The generate method returns either a previously generated element
// stored in the tip variable, or generates it and saves it in tip for
// later use, after which returns it.
return this.tip || (this.tip = $('<span class="colorTip">'+this.content+
'<span class="pointyTipShadow"></span><span class="pointyTip"></span></span>'));
},
show: function(){
if(this.shown) return;
// Center the tip and start a fadeIn animation
this.tip.css('margin-left',-this.tip.outerWidth()/2).fadeIn('fast');
this.shown = true;
},
hide: function(){
this.tip.fadeOut();
this.shown = false;
}
}
})(jQuery);
<?php
namespace App\FrontModule\Components;
use App;
use Nette\Application\UI\Control;
use Nette\Caching\Cache;
use Nette\Caching\IStorage;
/**
* Class Youtube
*/
class Youtube extends FrontControl
{
public $presets;
public $content;
public $cacheStorage;
public function __construct(App\Model\Presets $presets, IStorage $IStorage)
{
$this->presets = $presets;
$this->cacheStorage = $IStorage;
}
private function fetchData()
{
$user = $this->presets->defaults['keys']['youtube']['user'];
$path = "https://www.youtube.com/feeds/videos.xml?channel_id=$user";
try {
$out = json_decode(json_encode(@new \SimpleXMLIterator($path, null, true)), TRUE);
return $out;
} catch (\Exception $e) {
return false;
}
}
public function getData()
{
$cache = new Cache($this->cacheStorage, 'youtubePosts');
try {
$out = $cache->load("videos");
} catch (\Exception $e) {
$out = false;
}
if (empty($out)) {
try {
$data = self::fetchData();
if ($data) {
$out = $data['entry'];
$cache->save("videos", $out, array(
Cache::EXPIRATION => '+30 minutes',
Cache::SLIDING => TRUE
));
} else {
$out = false;
}
} catch (\Exception $e) {
$out = false;
}
}
return $out;
}
public function renderDefault(array $config = array())
{
$config = $this->getCurrentConfig($config);
$this->template->presets = $this->presets->getPresets();
$this->template->youtubeData = $this->getData();
$this->render($config);
}
}
<?php
namespace App\FrontModule\Components;
use App;
use Nette\Caching\Cache;
use Nette\Caching\IStorage;
use Nette\Utils\Json;
/**
* Class Instagram
*/
class Instagram extends FrontControl
{
public $presets;
public $content;
public $cacheStorage;
public function __construct(App\Model\Presets $presets, IStorage $IStorage)
{
$this->presets = $presets;
$this->cacheStorage = $IStorage;
}
private function fetchData()
{
$token = $this->presets->defaults['keys']['instagram']['token'];
$user = $this->presets->defaults['keys']['instagram']['user'];
$url = "https://api.instagram.com/v1/users/$user/media/recent/?access_token=$token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public function getData()
{
$cache = new Cache($this->cacheStorage, 'instagramPosts');
try {
$out = $cache->load("photos");
} catch (\Exception $e) {
$out = false;
}
if (empty($out)) {
try {
$data = self::fetchData();
$out = Json::decode($data, true);
$out = $out['data'];
$cache->save("photos", $out, array(
Cache::EXPIRATION => '+30 minutes',
Cache::SLIDING => TRUE
));
} catch (\Exception $e) {
$out = false;
}
}
return $out;
}
public function renderDefault(array $config = array())
{
$config = $this->getCurrentConfig($config);
$this->template->presets = $this->presets->getPresets();
$this->template->instagramData = $this->getData();
$this->render($config);
}
}
//--- demand methods --- //
@function to-string($value) {
@return inspect($value);
}
/// Replace `$search` with `$replace` in `$string`
/// @author Hugo Giraudel
/// @param {String} $string - Initial string
/// @param {String} $search - Substring to replace
/// @param {String} $replace ('') - New value
/// @return {String} - Updated string
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
/* HELPER */
$fontSizeStart: 0.1;
$fontSizeEnd : 6;
$fontUnit: 'rem';
@each $breakpoint in map-keys($grid-breakpoints)
{
@include media-breakpoint-up($breakpoint)
{
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
$i: $fontSizeStart;
@while $i <= $fontSizeEnd
{
$iSafe: str-replace(to-string($i), '.', '_');
.fs#{$infix}-#{$iSafe}
{
font-size: #{$i}#{$fontUnit};
}
$i: $i + 0.1;
}
}
}