mirror of https://github.com/grafana/grafana
Conflicts: public/sass/.sass-lint.yml tasks/options/sasslint.jspull/4119/head
commit
145c14ed57
@ -0,0 +1,253 @@ |
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code from https://github.com/gogits/gogs/blob/v0.7.0/modules/avatar/avatar.go
|
||||
|
||||
package avatar |
||||
|
||||
import ( |
||||
"bufio" |
||||
"bytes" |
||||
"crypto/md5" |
||||
"encoding/hex" |
||||
"fmt" |
||||
"io" |
||||
"io/ioutil" |
||||
"net/http" |
||||
"net/url" |
||||
"path/filepath" |
||||
"strconv" |
||||
"strings" |
||||
"sync" |
||||
"time" |
||||
|
||||
"github.com/grafana/grafana/pkg/log" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
) |
||||
|
||||
var gravatarSource string |
||||
|
||||
func UpdateGravatarSource() { |
||||
srcCfg := "//secure.gravatar.com/avatar/" |
||||
|
||||
gravatarSource = srcCfg |
||||
if strings.HasPrefix(gravatarSource, "//") { |
||||
gravatarSource = "http:" + gravatarSource |
||||
} else if !strings.HasPrefix(gravatarSource, "http://") && |
||||
!strings.HasPrefix(gravatarSource, "https://") { |
||||
gravatarSource = "http://" + gravatarSource |
||||
} |
||||
} |
||||
|
||||
// hash email to md5 string
|
||||
// keep this func in order to make this package independent
|
||||
func HashEmail(email string) string { |
||||
// https://en.gravatar.com/site/implement/hash/
|
||||
email = strings.TrimSpace(email) |
||||
email = strings.ToLower(email) |
||||
|
||||
h := md5.New() |
||||
h.Write([]byte(email)) |
||||
return hex.EncodeToString(h.Sum(nil)) |
||||
} |
||||
|
||||
// Avatar represents the avatar object.
|
||||
type Avatar struct { |
||||
hash string |
||||
reqParams string |
||||
data *bytes.Buffer |
||||
notFound bool |
||||
timestamp time.Time |
||||
} |
||||
|
||||
func New(hash string) *Avatar { |
||||
return &Avatar{ |
||||
hash: hash, |
||||
reqParams: url.Values{ |
||||
"d": {"404"}, |
||||
"size": {"200"}, |
||||
"r": {"pg"}}.Encode(), |
||||
} |
||||
} |
||||
|
||||
func (this *Avatar) Expired() bool { |
||||
return time.Since(this.timestamp) > (time.Minute * 10) |
||||
} |
||||
|
||||
func (this *Avatar) Encode(wr io.Writer) error { |
||||
_, err := wr.Write(this.data.Bytes()) |
||||
return err |
||||
} |
||||
|
||||
func (this *Avatar) Update() (err error) { |
||||
select { |
||||
case <-time.After(time.Second * 3): |
||||
err = fmt.Errorf("get gravatar image %s timeout", this.hash) |
||||
case err = <-thunder.GoFetch(gravatarSource+this.hash+"?"+this.reqParams, this): |
||||
} |
||||
return err |
||||
} |
||||
|
||||
type service struct { |
||||
notFound *Avatar |
||||
cache map[string]*Avatar |
||||
} |
||||
|
||||
func (this *service) mustInt(r *http.Request, defaultValue int, keys ...string) (v int) { |
||||
for _, k := range keys { |
||||
if _, err := fmt.Sscanf(r.FormValue(k), "%d", &v); err == nil { |
||||
defaultValue = v |
||||
} |
||||
} |
||||
return defaultValue |
||||
} |
||||
|
||||
func (this *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
||||
urlPath := r.URL.Path |
||||
hash := urlPath[strings.LastIndex(urlPath, "/")+1:] |
||||
|
||||
var avatar *Avatar |
||||
|
||||
if avatar, _ = this.cache[hash]; avatar == nil { |
||||
avatar = New(hash) |
||||
} |
||||
|
||||
if avatar.Expired() { |
||||
if err := avatar.Update(); err != nil { |
||||
log.Trace("avatar update error: %v", err) |
||||
} |
||||
} |
||||
|
||||
if avatar.notFound { |
||||
avatar = this.notFound |
||||
} else { |
||||
this.cache[hash] = avatar |
||||
} |
||||
|
||||
w.Header().Set("Content-Type", "image/jpeg") |
||||
w.Header().Set("Content-Length", strconv.Itoa(len(avatar.data.Bytes()))) |
||||
w.Header().Set("Cache-Control", "private, max-age=3600") |
||||
|
||||
if err := avatar.Encode(w); err != nil { |
||||
log.Warn("avatar encode error: %v", err) |
||||
w.WriteHeader(500) |
||||
} |
||||
} |
||||
|
||||
func CacheServer() http.Handler { |
||||
UpdateGravatarSource() |
||||
|
||||
return &service{ |
||||
notFound: newNotFound(), |
||||
cache: make(map[string]*Avatar), |
||||
} |
||||
} |
||||
|
||||
func newNotFound() *Avatar { |
||||
avatar := &Avatar{} |
||||
|
||||
// load transparent png into buffer
|
||||
path := filepath.Join(setting.StaticRootPath, "img", "transparent.png") |
||||
|
||||
if data, err := ioutil.ReadFile(path); err != nil { |
||||
log.Error(3, "Failed to read transparent.png, %v", path) |
||||
} else { |
||||
avatar.data = bytes.NewBuffer(data) |
||||
} |
||||
|
||||
return avatar |
||||
} |
||||
|
||||
// thunder downloader
|
||||
var thunder = &Thunder{QueueSize: 10} |
||||
|
||||
type Thunder struct { |
||||
QueueSize int // download queue size
|
||||
q chan *thunderTask |
||||
once sync.Once |
||||
} |
||||
|
||||
func (t *Thunder) init() { |
||||
if t.QueueSize < 1 { |
||||
t.QueueSize = 1 |
||||
} |
||||
t.q = make(chan *thunderTask, t.QueueSize) |
||||
for i := 0; i < t.QueueSize; i++ { |
||||
go func() { |
||||
for { |
||||
task := <-t.q |
||||
task.Fetch() |
||||
} |
||||
}() |
||||
} |
||||
} |
||||
|
||||
func (t *Thunder) Fetch(url string, avatar *Avatar) error { |
||||
t.once.Do(t.init) |
||||
task := &thunderTask{ |
||||
Url: url, |
||||
Avatar: avatar, |
||||
} |
||||
task.Add(1) |
||||
t.q <- task |
||||
task.Wait() |
||||
return task.err |
||||
} |
||||
|
||||
func (t *Thunder) GoFetch(url string, avatar *Avatar) chan error { |
||||
c := make(chan error) |
||||
go func() { |
||||
c <- t.Fetch(url, avatar) |
||||
}() |
||||
return c |
||||
} |
||||
|
||||
// thunder download
|
||||
type thunderTask struct { |
||||
Url string |
||||
Avatar *Avatar |
||||
sync.WaitGroup |
||||
err error |
||||
} |
||||
|
||||
func (this *thunderTask) Fetch() { |
||||
this.err = this.fetch() |
||||
this.Done() |
||||
} |
||||
|
||||
var client = &http.Client{} |
||||
|
||||
func (this *thunderTask) fetch() error { |
||||
this.Avatar.timestamp = time.Now() |
||||
|
||||
log.Debug("avatar.fetch(fetch new avatar): %s", this.Url) |
||||
req, _ := http.NewRequest("GET", this.Url, nil) |
||||
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/jpeg,image/png,*/*;q=0.8") |
||||
req.Header.Set("Accept-Encoding", "deflate,sdch") |
||||
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.8") |
||||
req.Header.Set("Cache-Control", "no-cache") |
||||
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36") |
||||
resp, err := client.Do(req) |
||||
|
||||
if err != nil { |
||||
this.Avatar.notFound = true |
||||
return fmt.Errorf("gravatar unreachable, %v", err) |
||||
} |
||||
|
||||
defer resp.Body.Close() |
||||
|
||||
if resp.StatusCode != 200 { |
||||
this.Avatar.notFound = true |
||||
return fmt.Errorf("status code: %d", resp.StatusCode) |
||||
} |
||||
|
||||
this.Avatar.data = &bytes.Buffer{} |
||||
writer := bufio.NewWriter(this.Avatar.data) |
||||
|
||||
if _, err = io.Copy(writer, resp.Body); err != nil { |
||||
return err |
||||
} |
||||
|
||||
return nil |
||||
} |
@ -1,19 +1,16 @@ |
||||
<div class="navbar-inner"> |
||||
<div class="top-nav-btn top-nav-menu-btn"> |
||||
<a class="pointer" ng-click="ctrl.contextSrv.toggleSideMenu()"> |
||||
<span class="top-nav-logo-background"> |
||||
<img class="logo-icon" src="public/img/grafana_icon.svg"></img> |
||||
</span> |
||||
<i class="icon-gf icon-gf-grafana_wordmark"></i> |
||||
<i class="fa fa-caret-down"></i> |
||||
</a> |
||||
</div> |
||||
<a class="navbar-brand-btn pointer" ng-click="ctrl.contextSrv.toggleSideMenu()"> |
||||
<span class="navbar-brand-btn-background"> |
||||
<img src="public/img/grafana_icon.svg"></img> |
||||
</span> |
||||
<i class="icon-gf icon-gf-grafana_wordmark"></i> |
||||
<i class="fa fa-caret-down"></i> |
||||
</a> |
||||
|
||||
|
||||
<div ng-if="ctrl.title"> |
||||
<nav-button title="{{ctrl.title}}" title-url="{{ctrl.titleUrl}}" icon="{{ctrl.icon}}"> |
||||
</nav-button> |
||||
</div> |
||||
<a href="{{::ctrl.titleUrl}}" class="navbar-page-btn" ng-show="ctrl.title"> |
||||
<i class="{{::ctrl.icon}}"></i> |
||||
{{::ctrl.title}} |
||||
</a> |
||||
|
||||
<div ng-transclude></div> |
||||
</div> |
||||
|
@ -1,14 +1,13 @@ |
||||
<navbar icon="fa fa-fw fa-cubes" title="{{ctrl.appModel.name}}" title-url="apps/{{ctrl.appId}}/edit"> |
||||
<navbar icon="icon-gf icon-gf-apps" title="{{ctrl.appModel.name}}" title-url="apps/{{ctrl.appId}}/edit"> |
||||
</navbar> |
||||
|
||||
<div class="page-container"> |
||||
<div class="page-wide"> |
||||
<div class="page-header"> |
||||
<h1>{{ctrl.page.name}}</h1> |
||||
</div> |
||||
|
||||
<div ng-if="ctrl.page"> |
||||
<plugin-component type="app-page"> |
||||
</plugin-component> |
||||
</div> |
||||
|
||||
<div ng-if="ctrl.page"> |
||||
<plugin-component type="app-page"> |
||||
</plugin-component> |
||||
</div> |
||||
</div> |
||||
|
@ -1,44 +1,22 @@ |
||||
<br> |
||||
<h5>CloudWatch details</h5> |
||||
<h3 class="page-heading">CloudWatch details</h3> |
||||
|
||||
<div class="editor-row"> |
||||
<div class="section tight-form-container" style="margin-bottom: 20px"> |
||||
<div class="tight-form"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 200px"> |
||||
Credentials profile name<tip>Credentials profile name, as specified in ~/.aws/credentials, leave blank for default</tip> |
||||
</li> |
||||
<li> |
||||
<input type="text" class="tight-form-input input-large last" ng-model='ctrl.current.database' placeholder="default"></input> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
</div> |
||||
<div class="tight-form"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 200px"> |
||||
Default Region<tip>Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.</tip> |
||||
</li> |
||||
<!-- |
||||
Whenever this list is updated, backend list should also be updated. |
||||
Please update the region list in pkg/api/cloudwatch/metric.go |
||||
--> |
||||
<li> |
||||
<select class="tight-form-input input-large last" ng-model="ctrl.current.jsonData.defaultRegion" ng-options="region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-west-1', 'us-west-2']"></select> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
</div> |
||||
<div class="tight-form"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 200px"> |
||||
Custom Metrics namespace<tip>Namespaces of Custom Metrics</tip> |
||||
</li> |
||||
<li> |
||||
<input type="text" class="tight-form-input input-large last" ng-model='ctrl.current.jsonData.customMetricsNamespaces' placeholder="Namespace1,Namespace2"></input> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
<div class="gf-form-group"> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label width-14"> |
||||
Credentials profile name<tip>Credentials profile name, as specified in ~/.aws/credentials, leave blank for default</tip> |
||||
</label> |
||||
<input type="text" class="gf-form-input max-width-15" ng-model='ctrl.current.database' placeholder="default"></input> |
||||
</div> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label width-14"> |
||||
Default Region<tip>Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.</tip> |
||||
</label> |
||||
<div class="gf-form-select-wrapper"> |
||||
<select class="gf-form-input max-width-15" ng-model="ctrl.current.jsonData.defaultRegion" ng-options="region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-west-1', 'us-west-2']"></select> |
||||
</div> |
||||
</div> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label width-14">Custom Metrics namespace<tip>Namespaces of Custom Metrics</tip></label> |
||||
<input type="text" class="gf-form-input max-width-15" ng-model='ctrl.current.jsonData.customMetricsNamespaces' placeholder="Namespace1,Namespace2"></input> |
||||
</div> |
||||
</div> |
||||
|
@ -1,52 +1,33 @@ |
||||
<datasource-http-settings current="ctrl.current"> |
||||
</datasource-http-settings> |
||||
|
||||
<h4>InfluxDB Details</h4> |
||||
<h3 class="page-heading">InfluxDB Details</h3> |
||||
|
||||
<div class="tight-form"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 80px"> |
||||
Database |
||||
</li> |
||||
<li> |
||||
<input type="text" class="tight-form-input input-large" ng-model='ctrl.current.database' placeholder="" required></input> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
</div> |
||||
<div class="tight-form last"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 80px"> |
||||
User |
||||
</li> |
||||
<li> |
||||
<input type="text" class="tight-form-input input-large" ng-model='ctrl.current.user' placeholder="" required></input> |
||||
</li> |
||||
<li class="tight-form-item"> |
||||
Password |
||||
</li> |
||||
<li> |
||||
<input type="password" class="tight-form-input input-large" ng-model='ctrl.current.password' placeholder="" required></input> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
</div> |
||||
<div class="gf-form-group"> |
||||
<div class="gf-form-inline"> |
||||
<div class="gf-form max-width-30"> |
||||
<span class="gf-form-label width-7">Database</span> |
||||
<input type="text" class="gf-form-input" ng-model='ctrl.current.database' placeholder="" required></input> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="gf-form-inline"> |
||||
<div class="gf-form max-width-15"> |
||||
<span class="gf-form-label width-7">User</span> |
||||
<input type="text" class="gf-form-input" ng-model='ctrl.current.user' placeholder="" required></input> |
||||
</div> |
||||
<div class="gf-form max-width-15"> |
||||
<span class="gf-form-label width-7">Password</span> |
||||
<input type="password" class="gf-form-input" ng-model='ctrl.current.password' placeholder="" required></input> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<br> |
||||
<h4>Default query settings</h4> |
||||
<div class="tight-form last"> |
||||
<ul class="tight-form-list"> |
||||
<li class="tight-form-item" style="width: 200px"> |
||||
Group by time interval |
||||
</li> |
||||
<li> |
||||
<input type="text" class="input-medium tight-form-input input-xlarge" ng-model="ctrl.current.jsonData.timeInterval" |
||||
spellcheck='false' placeholder="example: >10s"> |
||||
</li> |
||||
<li class="tight-form-item"> |
||||
<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >10s'" data-placement="right"></i> |
||||
</li> |
||||
</ul> |
||||
<div class="clearfix"></div> |
||||
<div class="gf-form-group"> |
||||
<div class="gf-form max-width-21"> |
||||
<span class="gf-form-label">Default group by time</span> |
||||
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval" |
||||
spellcheck='false' placeholder="example: >10s"></input> |
||||
<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >10s'" data-placement="right"></i> |
||||
</div> |
||||
</div> |
||||
|
@ -1,17 +1,26 @@ |
||||
<div> |
||||
<div class="row-fluid"> |
||||
<div class="span4"> |
||||
<label class="small">Mode</label> <select class="input-medium" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown','text']"></select> |
||||
</div> |
||||
<div class="span2" ng-show="ctrl.panel.mode == 'text'"> |
||||
<label class="small">Font Size</label> <select class="input-mini" ng-model="ctrl.panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select> |
||||
</div> |
||||
</div> |
||||
<div class="gf-form-group"> |
||||
<div class="gf-form-inline"> |
||||
<div class="gf-form"> |
||||
<span class="gf-form-label">Mode</span> |
||||
<span class="gf-form-select-wrapper"> |
||||
<select class="gf-form-input" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown','text']"></select> |
||||
</span> |
||||
</div> |
||||
|
||||
<label class=small>Content |
||||
<span ng-show="ctrl.panel.mode == 'markdown'">(This area uses <a target="_blank" href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>. HTML is not supported)</span> |
||||
</label> |
||||
|
||||
<textarea ng-model="ctrl.panel.content" rows="20" style="width:95%" ng-change="ctrl.render()" ng-model-onblur> |
||||
</textarea> |
||||
<div class="gf-form" ng-show="ctrl.panel.mode == 'text'"> |
||||
<span class="gf-form-label">Font Size</span> |
||||
<span class="gf-form-select-wrapper"> |
||||
<select class="gf-form-input" ng-model="ctrl.panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<h3 class="page-heading">Content</h3> |
||||
|
||||
<span ng-show="ctrl.panel.mode == 'markdown'"> |
||||
(This area uses <a target="_blank" href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>. HTML is not supported) |
||||
</span> |
||||
|
||||
<textarea class="gf-form-input" ng-model="ctrl.panel.content" rows="20" style="width:95%" ng-change="ctrl.render()" ng-model-onblur> |
||||
</textarea> |
||||
|
@ -1 +1,2 @@ |
||||
<p ng-bind-html="ctrl.content" ng-show="ctrl.content"></p> |
||||
<p class="panel-text-content" ng-bind-html="ctrl.content" ng-show="ctrl.content"> |
||||
</p> |
||||
|
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 95 B |
@ -1,33 +1,87 @@ |
||||
options: |
||||
formatter: stylish |
||||
|
||||
files: |
||||
include: '**/*.s+(a|c)ss' |
||||
ignore: |
||||
- './utils/*.scss' |
||||
|
||||
rules: |
||||
# Extends |
||||
extends-before-mixins: 0 |
||||
extends-before-declarations: 0 |
||||
placeholder-in-extend: 0 |
||||
|
||||
# Mixins |
||||
mixins-before-declarations: 0 |
||||
|
||||
# Line Spacing |
||||
one-declaration-per-line: 0 |
||||
empty-line-between-blocks: 0 |
||||
single-line-per-selector: 0 |
||||
|
||||
# Disallows |
||||
no-color-keywords: 0 |
||||
no-color-literals: 0 |
||||
no-css-comments: 0 |
||||
no-debug: 0 |
||||
no-duplicate-properties: 0 |
||||
no-empty-rulesets: 1 |
||||
# Consistency Rules |
||||
# extends-before-mixins: 1 |
||||
# extends-before-declarations: 1 |
||||
# mixins-before-declarations: 1 |
||||
# Require an empty line between blocks |
||||
# final-newline: 1 |
||||
# no-ids: 1 |
||||
# indentation: 0 |
||||
# leading-zero: 1 |
||||
# name-format: 0 |
||||
# nesting-depth: 1 |
||||
# placeholder-in-extend: 1 |
||||
# property-sort-order: 1 |
||||
# property-spelling: 0 |
||||
# shorthand: 1 |
||||
# one-declaration-per-line: 1 |
||||
# single-line-per-selector: 1 |
||||
# space-after-comma: 1 |
||||
# # Space surrounding colons |
||||
# space-before-colon: 1 |
||||
# space-after-colon: 1 |
||||
# |
||||
# space-before-brace: 1 |
||||
# |
||||
# space-between-parens: 1 |
||||
# trailing-semicolon: 1 |
||||
no-extends: 0 |
||||
no-ids: 0 |
||||
no-important: 0 |
||||
no-invalid-hex: 0 |
||||
no-mergeable-selectors: 0 |
||||
no-misspelled-properties: 0 |
||||
no-qualifying-elements: 0 |
||||
no-trailing-zero: 0 |
||||
no-transition-all: 0 |
||||
no-url-protocols: 0 |
||||
no-vendor-prefixes: 0 |
||||
no-warn: 0 |
||||
property-units: 0 |
||||
|
||||
# Nesting |
||||
force-attribute-nesting: 0 |
||||
force-element-nesting: 0 |
||||
force-pseudo-nesting: 0 |
||||
|
||||
# Name Formats |
||||
class-name-format: 0 |
||||
function-name-format: 0 |
||||
id-name-format: 0 |
||||
mixin-name-format: 0 |
||||
placeholder-name-format: 0 |
||||
variable-name-format: 0 |
||||
|
||||
# Style Guide |
||||
bem-depth: 0 |
||||
border-zero: 0 |
||||
brace-style: 0 |
||||
clean-import-paths: 0 |
||||
empty-args: 0 |
||||
hex-length: 0 |
||||
hex-notation: 0 |
||||
indentation: 0 |
||||
leading-zero: 0 |
||||
nesting-depth: 0 |
||||
property-sort-order: 0 |
||||
quotes: 0 |
||||
shorthand-values: 0 |
||||
url-quotes: 0 |
||||
variable-for-property: 0 |
||||
zero-unit: 0 |
||||
|
||||
# Inner Spacing |
||||
space-after-comma: 0 |
||||
space-before-colon: 0 |
||||
space-after-colon: 0 |
||||
space-before-brace: 0 |
||||
space-before-bang: 0 |
||||
space-after-bang: 0 |
||||
space-between-parens: 0 |
||||
space-around-operator: 0 |
||||
|
||||
# Final Items |
||||
trailing-semicolon: 0 |
||||
final-newline: 0 |
||||
|
@ -0,0 +1,6 @@ |
||||
|
||||
.panel-text-content { |
||||
ul { |
||||
margin: 0 0 $spacer $spacer * 1.5; |
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
@mixin keyframes($animation-name) { |
||||
@-webkit-keyframes #{$animation-name} { |
||||
@content; |
||||
} |
||||
@-moz-keyframes #{$animation-name} { |
||||
@content; |
||||
} |
||||
@-ms-keyframes #{$animation-name} { |
||||
@content; |
||||
} |
||||
@-o-keyframes #{$animation-name} { |
||||
@content; |
||||
} |
||||
@keyframes #{$animation-name} { |
||||
@content; |
||||
} |
||||
} |
||||
|
||||
@mixin animation($str) { |
||||
-webkit-animation: #{$str}; |
||||
-moz-animation: #{$str}; |
||||
-ms-animation: #{$str}; |
||||
-o-animation: #{$str}; |
||||
animation: #{$str}; |
||||
} |
@ -0,0 +1,19 @@ |
||||
|
||||
|
||||
.max-width { width: 100%; } |
||||
.width-auto { width: auto; } |
||||
|
||||
// widths |
||||
@for $i from 1 through 30 { |
||||
.width-#{$i} { |
||||
width: ($spacer * $i) - $gf-form-margin; |
||||
} |
||||
} |
||||
|
||||
@for $i from 1 through 30 { |
||||
.max-width-#{$i} { |
||||
max-width: ($spacer * $i) - $gf-form-margin; |
||||
flex-grow: 1; |
||||
} |
||||
} |
||||
|
@ -1,10 +1,12 @@ |
||||
module.exports = function(config) { |
||||
'use strict'; |
||||
|
||||
return { |
||||
options: { |
||||
configFile: 'public/sass/.sass-lint.yml', |
||||
}, |
||||
target: ['public/sass/**/*.scss', '!public/sass/base/_normalize.scss'] |
||||
target: [ |
||||
'public/sass/*.scss', |
||||
'public/sass/components/*.scss', |
||||
] |
||||
}; |
||||
}; |
||||
|
Loading…
Reference in new issue