├── .gitattributes ├── .gitignore ├── .mversionrc ├── LICENSE ├── Procfile ├── README.md ├── bower.json ├── cron └── letsencrypt ├── daemon ├── selenium.sh └── xvfb.sh ├── docs ├── design_data │ ├── Untitled-1.ai │ ├── css-prop.ai │ ├── html-tag.ai │ ├── html-validator.logo.ai │ ├── js-logo.ai │ ├── style-validator.cover.1280x800.ai │ ├── style-validator.cover.1400x560.ai │ ├── style-validator.cover.440x280.ai │ ├── style-validator.cover.920x680.ai │ ├── style-validator.logo.1280x800.ai │ ├── style-validator.logo.2015.09.22.ai │ ├── style-validator.logo.ai │ └── style-validator.logo.with.nopadding.ai ├── opera │ ├── extension.crx │ └── extension.pem ├── slide │ ├── style-validator-html5etcstudy20151125.pdf │ └── style-validator-tpac20151028.pdf └── video_data │ └── style-validator.mov ├── gulpfile.js ├── make.zip.4.release.chrome.extension.sh ├── package.json ├── riskystyles.md ├── src ├── app.js ├── bookmarklet │ └── style-validator.js ├── bower_components │ ├── es6-promise │ │ ├── bower.json │ │ ├── es6-promise.js │ │ ├── es6-promise.min.js │ │ ├── promise.js │ │ ├── promise.min.js │ │ └── test │ │ │ ├── browserify.js │ │ │ ├── es6-promise.js │ │ │ ├── es6-promise.min.js │ │ │ ├── index.html │ │ │ ├── json3.js │ │ │ ├── mocha.css │ │ │ ├── mocha.js │ │ │ └── worker.js │ ├── polymer │ │ ├── LICENSE.txt │ │ ├── bower.json │ │ ├── build.log │ │ ├── polymer-micro.html │ │ ├── polymer-mini.html │ │ └── polymer.html │ └── webcomponentsjs │ │ ├── CustomElements.js │ │ ├── CustomElements.min.js │ │ ├── HTMLImports.js │ │ ├── HTMLImports.min.js │ │ ├── MutationObserver.js │ │ ├── MutationObserver.min.js │ │ ├── README.md │ │ ├── ShadowDOM.js │ │ ├── ShadowDOM.min.js │ │ ├── bower.json │ │ ├── build.log │ │ ├── package.json │ │ ├── webcomponents-lite.js │ │ ├── webcomponents-lite.min.js │ │ ├── webcomponents.js │ │ └── webcomponents.min.js ├── dom_modules │ ├── footer.html │ ├── header.html │ ├── jsonld.html │ ├── result.html │ └── slide-share.html ├── extension │ ├── background.html │ ├── background.js │ ├── common.css │ ├── common.js │ ├── data │ │ ├── README.md │ │ ├── rules.json │ │ ├── special-kw-vals.json │ │ ├── tags-all.json │ │ ├── tags-empty.json │ │ ├── tags-filter.json │ │ ├── tags-replaced-element.json │ │ └── tags-table-children.json │ ├── devtools-detect.js │ ├── devtools.html │ ├── devtools.js │ ├── favicon.ico │ ├── google-analytics-options.js │ ├── google-analytics.js │ ├── iconmonstr-cube-1.svg │ ├── iconmonstr-cube-2.svg │ ├── iconmonstr-download-2-icon-active.svg │ ├── iconmonstr-download-2-icon.svg │ ├── iconmonstr-edit-8-icon-white.svg │ ├── iconmonstr-edit-8-icon.svg │ ├── iconmonstr-help-6-icon.svg │ ├── iconmonstr-link-4-icon.svg │ ├── iconmonstr-link-5-icon.svg │ ├── iconmonstr-link-icon-gray.svg │ ├── iconmonstr-magnifier-6.svg │ ├── iconmonstr-menu-1.svg │ ├── iconmonstr-menu-2.svg │ ├── iconmonstr-minus-2-icon.svg │ ├── iconmonstr-plus-2-icon.svg │ ├── iconmonstr-refresh-3-icon-active.svg │ ├── iconmonstr-refresh-3-icon.svg │ ├── iconmonstr-responsive.svg │ ├── iconmonstr-responsive3.svg │ ├── iconmonstr-responsive4.svg │ ├── iconmonstr-save-5-icon.svg │ ├── iconmonstr-save-icon-active.svg │ ├── iconmonstr-save-icon.svg │ ├── iconmonstr-selection-10-icon.svg │ ├── iconmonstr-undo-4-icon.svg │ ├── iconmonstr-upload-4.svg │ ├── iconmonstr-view-6.svg │ ├── iconmonstr-x-mark-3-icon.svg │ ├── iconmonstr-x-mark-icon.svg │ ├── manifest.json │ ├── options.css │ ├── options.html │ ├── options.js │ ├── panel.html │ ├── panel.js │ ├── popup.css │ ├── popup.html │ ├── popup.js │ ├── randomColor.js │ ├── specificity.js │ ├── style-validator-for-console.bak │ ├── style-validator-for-console.css │ ├── style-validator-for-elements.css │ ├── style-validator.js │ ├── style-validator.logo.black.svg │ ├── style-validator.logo.png │ ├── style-validator.logo.svg │ ├── style-validator.logo_16x16.png │ ├── style-validator.logo_200x200.png │ └── webcomponents.min.js ├── favicon.ico ├── gif_animations │ └── demo.gif ├── img │ ├── GitHub-Mark-32px-lightgreen.svg │ ├── bookmarkbar.png │ ├── browserstack-logo.svg │ ├── chromeWebStore.png │ ├── chrome_128x128.png │ ├── css-prop.svg │ ├── edge_128x128.png │ ├── edit-page.png │ ├── extension-import.png │ ├── firefox_128x128.png │ ├── html-tag.svg │ ├── html-validator.logo.png │ ├── iconmonstr-chart-19.svg │ ├── iconmonstr-cube-17.svg │ ├── iconmonstr-cube-18.svg │ ├── iconmonstr-edit-8-icon.svg │ ├── iconmonstr-flask-7-icon.svg │ ├── iconmonstr-help-3-icon.svg │ ├── iconmonstr-link-icon.svg │ ├── iconmonstr-note-19.svg │ ├── iconmonstr-refresh-3-icon.svg │ ├── internet-explorer_128x128.png │ ├── js-logo.svg │ ├── macbook-pro-retina.png │ ├── opera_128x128.png │ ├── safari_128x128.png │ ├── screenshot-console.png │ ├── screenshot-rulepage.1280x800.png │ ├── screenshot-rulepage.png │ ├── screenshot-validator.1280x800.png │ ├── screenshot-validator.png │ ├── style-validator.cover.1280x800.png │ ├── style-validator.cover.1400x560.png │ ├── style-validator.cover.440x280.png │ ├── style-validator.cover.920x680.png │ ├── style-validator.logo.nopadding.64x64.png │ ├── style-validator.logo.nopadding.svg │ ├── style-validator.logo.svg │ └── style-validator.logo_128x128.png ├── index.html ├── page │ ├── analytics.html │ ├── common.css │ ├── demo-by-rules.html │ ├── demo-simple.hbs │ ├── demo-simple.html │ ├── demo-simple.jsbin.embed.html │ ├── demo.css │ ├── demo.html │ ├── demo1.css │ ├── demo1.html │ ├── demo2.css │ ├── demo2.html │ ├── demo3.css │ ├── demo3.html │ ├── demo4.html │ ├── handlebars.min.js │ ├── index.css │ ├── index.js │ ├── jquery-2.1.4.min.js │ ├── references.css │ ├── references.html │ ├── result.css │ ├── result.hbs │ ├── result.html │ ├── result.js │ └── vivus.min.js └── webdriverio.test.js ├── videos ├── style-validator.jpg ├── style-validator.m4v └── style-validator.webm └── why.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /.tmp 3 | *.zip 4 | *.key 5 | .DS_Store 6 | .bower.json 7 | task.md 8 | zip.command 9 | .idea 10 | Thumbs.db 11 | videos 12 | docs 13 | dest 14 | dump-dir 15 | *.iml 16 | npm-debug.log -------------------------------------------------------------------------------- /.mversionrc: -------------------------------------------------------------------------------- 1 | { 2 | "commitMessage": "v%s", 3 | "tagName": "v%s-src" 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Igari Takeharu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: cd ./dest && node app.js; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Style Validator 3 | ============================ 4 | 5 | [Style Validator](http://style-validator.io) 6 | is CSS Validator that can detect `Risky Style` that might break layout **after JavaScript** or **after CSS Media Queries**. 7 | 8 | # Installation 9 | 10 | - **[Chrome Extension](https://chrome.google.com/webstore/detail/style-validator/aaeahhnjkelemfcdmkcpaggdhfaffeod)**(In conjunction with Chrome DevTools) 11 | - **[JavaScript Bookmarklet](https://style-validator.io/)**(Currently, supported only Google Chrome and Opera) 12 | 13 | # Usage 14 | 15 | 1. Install from [Chrome Web Store](https://chrome.google.com/webstore/detail/style-validator/aaeahhnjkelemfcdmkcpaggdhfaffeod) or [Bookmarklet](http://style-validator.io) 16 | 2. Click `extension icon` or Press `shortcut key` (MAC: command + shift + i / WIN: ctrl + shift + i) 17 | ![Validator Screenshot](https://style-validator.io/img/screenshot-validator.png?v=2) 18 | [Little Movie (Gif Animation)](https://style-validator.io/gif_animations/demo.gif) 19 | 20 | ## Rule Editor 21 | 22 | If you want to edit default rule, use rule editor page like below. 23 | 24 | 1. Click `RuleID(e.g. Rule-2)` or go to `options page of extension` 25 | ![Rule page Screenshot](https://style-validator.io/img/screenshot-console.png) 26 | 2. Edit Rules or Make Your Presets(shareable) 27 | ![Console Screenshot](https://style-validator.io/img/screenshot-rulepage.png) 28 | 29 | 30 | # Goal 31 | 32 | - Reducing `tests`, `patches` and `costs` 33 | - Keeping engineer creative 34 | - Efficient education of safety HTML/CSS 35 | 36 | And, becoming a little help for Web 37 | 38 | # References 39 | 40 | - [Why we need to detect `Risky Style`?](https://github.com/Style-Validator/style-validator.herokuapp.com/blob/master/why.md) 41 | - [A part of introduction for `Risky Style` 42 | ](https://github.com/Style-Validator/style-validator.herokuapp.com/blob/master/riskystyles.md) 43 | 44 | # Open source project 45 | 46 | Dear Web Engineers, 47 | 48 | Please feel free to send me any feedback and Pull requests. 49 | If you need, check it out the document for developer. 50 | 51 | ## Contributing Source Code 52 | 53 | 1. Fork it 54 | 2. Create your feature branch (git checkout -b my-new-feature) 55 | 3. Commit your changes (git commit -am 'Add some feature') 56 | 4. Push to the branch (git push origin my-new-feature) 57 | 5. Create new Pull Request 58 | 59 | ## Contributing Validation Rules 60 | 61 | You can request from `options page of extension` or [edit page of web](https://style-validator.io/extension/options.html) 62 | 63 | ## Supported by 64 | 65 | 66 | 67 | BrowserStack is a awesome cloud testing service what uses real browsers and devices. 68 | 69 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Style-Validator", 3 | "version": "0.6.1", 4 | "homepage": "https://style-validator.io/", 5 | "authors": [ 6 | "Igari Takeharu" 7 | ], 8 | "description": "A CSS Validator that can validate after modified by JavaScript or CSS Media Queries.", 9 | "main": "style-validator.js", 10 | "moduleType": [], 11 | "keywords": [ 12 | "CSS", 13 | "Validator", 14 | "CSS Validator" 15 | ], 16 | "license": "MIT", 17 | "private": true, 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ], 25 | "dependencies": { 26 | "polymer": "Polymer/polymer#^1.2.0", 27 | "es6-promise": "^3.1.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cron/letsencrypt: -------------------------------------------------------------------------------- 1 | /home/ec2-user/certbot/certbot-auto renew --force-renew 2 | forever restart /home/ec2-user/app/style-validator/dest/app.js 3 | -------------------------------------------------------------------------------- /daemon/selenium.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # chkconfig: 345 96 49 3 | # description: Starts xvfb on display 99 4 | # processname: selenium standalone 5 | # 6 | # Note that this script requires you to have 7 | # an X window running on Display :99 8 | # This can be done by running: /usr/bin/Xvfb :99 -ac -screen 0 1024x768x8 & 9 | # You can save this script as /etc/init.d/selenium to start and stop selenium 10 | 11 | PORT=4444 12 | 13 | DESC="Selenium server" 14 | RUN_AS=selenium 15 | JAVA_BIN=/usr/bin/java 16 | 17 | PID_FILE="/var/run/selenium.pid" 18 | JAR_FILE="/var/lib/selenium-server-standalone-2.53.0.jar" 19 | LOG_FILE="/var/log/selenium" 20 | CHROME_DRIVER="/usr/bin/chromedriver" 21 | 22 | DAEMON_OPTS=" -jar $JAR_FILE -Dwebdriver.chrome.driver=$CHROME_DRIVER -log $LOG_FILE -port $PORT" 23 | 24 | NAME=selenium 25 | 26 | export DISPLAY=:99 27 | 28 | case "$1" in 29 | start) 30 | echo -n "Starting $DESC: " 31 | start-stop-daemon --make-pidfile --pidfile /var/run/selenium.pid --start --background --exec /usr/bin/java -- -jar /var/lib/selenium/selenium-server-standalone-2.53.0.jar -Dwebdriver.chrome.driver=/usr/bin/chromedriver 32 | echo "$NAME." 33 | ;; 34 | 35 | stop) 36 | echo -n "Stopping $DESC: " 37 | start-stop-daemon --stop --pidfile $PID_FILE 38 | echo "$NAME." 39 | ;; 40 | 41 | restart|force-reload) 42 | echo -n "Restarting $DESC: " 43 | start-stop-daemon --stop --pidfile $PID_FILE 44 | sleep 1 45 | start-stop-daemon --make-pidfile --pidfile /var/run/selenium.pid --start --background --exec /usr/bin/java -- -jar /var/lib/selenium/selenium-server-standalone-2.53.0.jar -Dwebdriver.chrome.driver=/usr/bin/chromedriver 46 | echo "$NAME." 47 | ;; 48 | 49 | *) 50 | N=/etc/init.d/$NAME 51 | echo "Usage: $N {start|stop|restart|force-reload}" >&2 52 | exit 1 53 | ;; 54 | esac -------------------------------------------------------------------------------- /daemon/xvfb.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # chkconfig: 345 95 50 3 | # description: Starts xvfb on display 99 4 | # processname: xvfb 5 | 6 | XVFB=/usr/bin/Xvfb 7 | XVFBARGS=":99 -screen 0, 1366x768x24 -nolisten tcp" 8 | PIDFILE=/var/run/xvfb.pid 9 | 10 | case "$1" in 11 | 12 | start) 13 | echo -n "Starting virtual X frame buffer: Xvfb" 14 | start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS 15 | echo "." 16 | ;; 17 | 18 | stop) 19 | echo -n "Stopping virtual X frame buffer: Xvfb" 20 | read pid <$PIDFILE 21 | pkill -TERM -P $pid 22 | echo "." 23 | ;; 24 | 25 | restart) 26 | $0 stop 27 | $0 start 28 | ;; 29 | 30 | *) 31 | echo "Usage: /etc/init.d/xvfb {start|stop|restart}" 32 | exit 1 33 | esac 34 | 35 | exit 0 -------------------------------------------------------------------------------- /docs/design_data/Untitled-1.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/Untitled-1.ai -------------------------------------------------------------------------------- /docs/design_data/css-prop.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/css-prop.ai -------------------------------------------------------------------------------- /docs/design_data/html-tag.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/html-tag.ai -------------------------------------------------------------------------------- /docs/design_data/html-validator.logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/html-validator.logo.ai -------------------------------------------------------------------------------- /docs/design_data/js-logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/js-logo.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.cover.1280x800.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.cover.1280x800.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.cover.1400x560.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.cover.1400x560.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.cover.440x280.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.cover.440x280.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.cover.920x680.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.cover.920x680.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.logo.1280x800.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.logo.1280x800.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.logo.2015.09.22.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.logo.2015.09.22.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.logo.ai -------------------------------------------------------------------------------- /docs/design_data/style-validator.logo.with.nopadding.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/design_data/style-validator.logo.with.nopadding.ai -------------------------------------------------------------------------------- /docs/opera/extension.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/opera/extension.crx -------------------------------------------------------------------------------- /docs/opera/extension.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDTITsnrJtVuWMV 3 | 16DiLhGX4QyGZx2BJzV79V5hqQ1wa6BGyXxZCOOfVJRr7CPtr7rJHZf9UHKuROeP 4 | oBj4iwQRNXSlFlEiC8Z1uB2+9NimKpcd+B3FY49Rkk4j4QgtAuqv7ESkebxeREUw 5 | xxxO8cBv4UU/4CQyR5IDGBWqlRoFgKZuYpo+uvoqHpPGCTtrr9WwQF4wAUS1E/Jw 6 | 2a++bga65GMIueMxqgtZyNHXTa+an8P7ReMBxOEDcZRvQinAQbW+M7FQhC3n4C1H 7 | nPsYiP5bF8f7+4qIcK6yKMWRrOcg3MKp1MhPVsPWRsDbr1K3q7+8dPJOhsDtz9dj 8 | DL9krJjzAgMBAAECggEBAJWGPWzVs5U8nE4Fzm0hD1ivC73MHXswl5JYriUgIuJx 9 | dqtrWuN7hil7LzpXnQJiqDhy+wduCCofppdzXPv5CEJfx2J7sa4ZBM6uPHLW2PCl 10 | zSxuYjc/UWsF4M1MPAwUur0o6VxK0vs4AoCPIx9N22ng8rhQN5JcWa5TSlTrD+jA 11 | cKV+9DNiprnqRpjkz6vaGqvlRMJmSnU51umQ6I2CuJ4KT1rdIMd/T4aOJvo60zOA 12 | pIAzK95M/ja9MBEtYitDWwHFczKMXxxYW1L3iTaCaaVqwMIAPI5zKNa9fcXAsA7J 13 | 2rLgKtfDn3UX9rFpwLLjLxOy5lSB6/QasENoFAem7uECgYEA8BWdSN49WgACLYtJ 14 | S7b2h6bOyacdjFEaF4bQTYjiC9apcgBVZqXBoNmP/JuYiEB/969mYjMZYf8eNaN+ 15 | ocWygUjU71AfvyJlTjtsKZuwea5osyW9Gfzf2a1UwU7MswdgaEWqF+Nm62ZgcSvP 16 | W+nMapE13IM39pVEx8SgIY5XYrsCgYEA4SA9AfCQXfD8cHLsdHkoJ22HmEPcn10O 17 | zXLNSQXRqcOjm8Q6dbQo+ckHhrjvM+orfbSujrtFux25AcSpqq3fmTX4ua8d/Vha 18 | CIoeG8VuzkwjFYREEs9Gy3/g/1tGMAVauNBd15f4f4h4H0v5aY7JLq0mQPwCSWy0 19 | YbZQ3YKzSykCgYEA47D8DAGJWfOsHRl+F+qbgCc48pIlOdAo2Ksonn/1MZkR9mZO 20 | mB0Xt77eCYpfbMkPFA4rIXKo3gGf2usFy9K86lPybkwk75ZlUX6VpBhdk+lOrqhZ 21 | 4W2rtrvmJ7bd9+RFEF8RY7ps/0+Go44TCG6BSYgR9uITjy4dnv/hhjGCusUCgYEA 22 | 0BIX0N8iz3CYIOZXHR+NuUNGe7jdBH3h3Ikqqz8xlRI4+RLYZUlqRdNDnYT3sKfS 23 | IpEIdOspe9Pw1m2J0zJ44wY7KINt2GX8cMAXK9vCmfFMy+o/cJMa/6LltZ4KtP99 24 | 5irPUSAokNb1DxgNIT7TOszV+mHxSyOpZFY5T0IprGECgYAy8UAXu07h8mnDRu7J 25 | Knk8ytzTt1Q9Tu5sSZQUcbvHKnvsDnD7EF5fFysY9Q6y4hAQNPMLwe+H4dIad3RS 26 | OGv0KtPrCdXJRBcY6rwhOnrGtqN0xqQD//3MeVc/ahKSVLHQzqIly+9PYw77N5RE 27 | s8Y9ksDI+C2E9j8LgFp5eCo12Q== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /docs/slide/style-validator-html5etcstudy20151125.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/slide/style-validator-html5etcstudy20151125.pdf -------------------------------------------------------------------------------- /docs/slide/style-validator-tpac20151028.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/slide/style-validator-tpac20151028.pdf -------------------------------------------------------------------------------- /docs/video_data/style-validator.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/docs/video_data/style-validator.mov -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var buffer = require('buffer'); 2 | var del = require('del'); 3 | var map = require('map-stream'); 4 | var gulp = require('gulp'); 5 | var gulpUglify = require('gulp-uglify'); 6 | var postcss = require('gulp-postcss'); 7 | var sourcemaps = require('gulp-sourcemaps'); 8 | var autoprefixer = require('autoprefixer'); 9 | 10 | gulp.task('clean', clean); 11 | gulp.task('build', ['clean'], function() { 12 | return copy().on('end', function() { 13 | autoprefix(); 14 | bookmarklet(); 15 | }); 16 | }); 17 | gulp.task('live', function() { 18 | return copy('!./src/**/app.js').on('end', function() { 19 | autoprefix(); 20 | bookmarklet(); 21 | }); 22 | }); 23 | gulp.task('watch',function(){ 24 | gulp.watch('./src/**/*', ['live']); 25 | }); 26 | gulp.task('default', ['live', 'watch']); 27 | 28 | function autoprefix() { 29 | return gulp.src('./src/**/*.css') 30 | .pipe(sourcemaps.init()) 31 | .pipe(postcss([ autoprefixer({ browsers: ['last 3 versions'] }) ])) 32 | .pipe(sourcemaps.write('.')) 33 | .pipe(gulp.dest('./dest')); 34 | } 35 | 36 | function bookmarklet() { 37 | var header = new Buffer('javascript:void '); 38 | return gulp.src('./src/bookmarklet/style-validator.js') 39 | .pipe(gulpUglify()) 40 | .pipe(map(function (file, cb) { 41 | file.contents = buffer.Buffer.concat([header, file.contents]); 42 | cb(null, file); 43 | })) 44 | .pipe(gulp.dest('./dest/bookmarklet')); 45 | } 46 | 47 | function copy(exceptionSrc) { 48 | var targetSrc = ['./src/**/*', './src/**/.*']; 49 | if(typeof exceptionSrc === 'string') { 50 | targetSrc.push(exceptionSrc); 51 | } 52 | return gulp.src(targetSrc) 53 | .pipe(gulp.dest('./dest')); 54 | } 55 | 56 | function clean() { 57 | return del(['./dest']); 58 | } -------------------------------------------------------------------------------- /make.zip.4.release.chrome.extension.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rm -rf Style-Validator.zip 3 | cd ./dest 4 | zip -r ../Style-Validator.zip ./extension -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "Style-Validator", 4 | "description": "A CSS Validator that can validate after modified by JavaScript or CSS Media Queries.", 5 | "keywords": [ 6 | "CSS", 7 | "Validator", 8 | "CSS Validator", 9 | "Style Validator" 10 | ], 11 | "author": "Igari Takeharu", 12 | "contributors": [ 13 | "Igari Takeharu" 14 | ], 15 | "version": "0.6.1", 16 | "license": "MIT", 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/Style-Validator/Style-Validator.git" 20 | }, 21 | "dependencies": { 22 | "autoprefixer": "^6.3.6", 23 | "console-stamp": "^0.2.0", 24 | "del": "^2.2.0", 25 | "devtools-detect": "^2.0.0", 26 | "gulp": "^3.9.1", 27 | "gulp-cli": "^1.2.1", 28 | "gulp-postcss": "^6.1.1", 29 | "gulp-sourcemaps": "^1.6.0", 30 | "gulp-uglify": "^1.5.3", 31 | "handlebars": "^4.0.5", 32 | "headless": "^1.0.0", 33 | "kerberos": "0.0.17", 34 | "map-stream": "^0.1.0", 35 | "mongodb": "^2.1.4", 36 | "node-uuid": "^1.4.7", 37 | "nodemailer": "^2.2.1", 38 | "open": "0.0.5", 39 | "request-ip": "^1.1.4", 40 | "selenium-standalone": "^5.0.0", 41 | "webdriverio": "^4.0.3" 42 | }, 43 | 44 | "devDependencies": { 45 | "del": "^2.2.0" 46 | }, 47 | "scripts": { 48 | "start": "git pull origin master && gulp build && cd dest && forever start app.js", 49 | "restart": "npm stop && npm start", 50 | "stop": "cd dest && forever stop app.js", 51 | "xvfb:start": "/etc/rc.d/init.d/xvfb start", 52 | "xvfb:restart": "/etc/rc.d/init.d/xvfb restart", 53 | "xvfb:stop": "/etc/rc.d/init.d/xvfb stop", 54 | "selenium:start": "/etc/rc.d/init.d/selenium start", 55 | "selenium:restart": "/etc/rc.d/init.d/selenium restart", 56 | "selenium:stop": "/etc/rc.d/init.d/selenium stop", 57 | "selenium:kill": "/etc/rc.d/init.d/selenium kill", 58 | "postinstall": "gulp build", 59 | "build": "gulp build && sh ./make.zip.4.release.chrome.extension.sh" 60 | }, 61 | "engines": { 62 | "node": "6.4.0", 63 | "npm": "3.10.3" 64 | }, 65 | "homepage": "http://style-validator.io" 66 | } 67 | -------------------------------------------------------------------------------- /riskystyles.md: -------------------------------------------------------------------------------- 1 | A part of introduction for `Risky Style` 2 | ============================ 3 | 4 | # Static Risky Style 5 | 6 | If you want to view them all, see the [rules page](https://style-validator.io/extension/options.html) 7 | 8 | ## No parent table-cell 9 | 10 | * **✗ NG** 11 | Parent that should be table is none 12 | ```html 13 |
14 |

15 |
16 | ``` 17 | 18 | * **✓ OK** 19 | ```html 20 |
21 |

22 |
23 | ``` 24 | 25 | ## Inline with size and margin 26 | 27 | * **✗ NG** 28 | Non-effective styles 29 | ```css 30 | span { 31 | width: 300px;/* no effect */ 32 | height: 300px;/* no effect */ 33 | margin-top: 30px; /* no effect */ 34 | margin-bottom: 30px; /* no effect */ 35 | } 36 | ``` 37 | 38 | * **✓ OK** 39 | ```css 40 | span { 41 | margin-right: 30px; /* effect */ 42 | margin-left: 30px; /* effect */ 43 | } 44 | ``` 45 | 46 | ## Pseudo element in Empty element 47 | 48 | * **✗ NG** 49 | Risky. Because old some browser may render this... 50 | ```html 51 | 52 | ``` 53 | ```css 54 | img::after { 55 | content: url(fuga.jpg); /* no effect but risky */ 56 | } 57 | ``` 58 | 59 | # Dynamic Risky Style 60 | 61 | ## Mistake in Media Query 62 | 63 | Here is base code 64 | ```css 65 | .parent { display: table; } 66 | .child { display: table-cell; } 67 | ``` 68 | ```html 69 |
70 |

71 |
72 | ``` 73 | 74 | ### When width of viewport is less than 640px 75 | 76 | * **✗ NG** 77 | ```css 78 | @media (max-width: 640px) { 79 | .parent { display: block; } /* .child is no parent table-cell */ 80 | } 81 | ``` 82 | ```html 83 |
84 |

85 |
86 | ``` 87 | 88 | * **✓ OK** 89 | ```css 90 | @media (max-width: 640px) { 91 | .parent, 92 | .child { display: block; } 93 | } 94 | ``` 95 | ```html 96 |
97 |

98 |
99 | ``` 100 | 101 | ## Mistake after JavaScript 102 | 103 | Here is base code 104 | ```css 105 | .parent { display: table; } 106 | .child { display: table-cell; } 107 | ``` 108 | ```html 109 |
110 |

111 |
112 | ``` 113 | 114 | ### When JavaScript is executed 115 | 116 | * **✗ NG** 117 | Insert inline element into table element 118 | ```js 119 | var parent = document.querySelector('.parent'); 120 | var newChild = document.createElement('div'); 121 | newChild.style.display = "inline";//mistake 122 | parent.appendChild(newChild); 123 | ``` 124 | ```html 125 |
126 |

127 |
128 |
129 | ``` 130 | 131 | * **✓ OK** 132 | To fix, convert inline to table-cell. 133 | ```js 134 | var parent = document.querySelector('.parent'); 135 | var newChild = document.createElement('div'); 136 | newChild.style.display = "table-cell";//correct 137 | parent.appendChild(newChild); 138 | ``` 139 | ```html 140 |
141 |

142 |
143 |
144 | ``` 145 | -------------------------------------------------------------------------------- /src/bookmarklet/style-validator.js: -------------------------------------------------------------------------------- 1 | (function(document) { 2 | var sv = document.createElement('script'); 3 | sv.src = '//style-validator.io/extension/style-validator.js?mode=manual'; 4 | //sv.src = 'http://localhost:8080/extension/style-validator.js?mode=manual'; 5 | sv.addEventListener('load', function() { 6 | console.groupEnd(); 7 | console.group('Style Validator: Executed by ' + STYLEV.caller + '.'); 8 | STYLEV.VALIDATOR.execute(); 9 | }); 10 | document.head.appendChild(sv); 11 | }(document)); -------------------------------------------------------------------------------- /src/bower_components/es6-promise/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-promise", 3 | "version": "3.1.2", 4 | "description": "A polyfill for ES6-style Promises, tracking rsvp", 5 | "authors": [ 6 | "Stefan Penner " 7 | ], 8 | "main": "./promise.js", 9 | "keywords": [ 10 | "promise" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/jakearchibald/ES6-Promises.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/jakearchibald/ES6-Promises/issues" 18 | }, 19 | "license": "MIT" 20 | } 21 | -------------------------------------------------------------------------------- /src/bower_components/es6-promise/es6-promise.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+. 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE 6 | * @version 3.1.2 7 | */ 8 | 9 | (function(){"use strict";function t(t){return"function"==typeof t||"object"==typeof t&&null!==t}function e(t){return"function"==typeof t}function n(t){W=t}function r(t){H=t}function o(){return function(){process.nextTick(a)}}function i(){return function(){U(a)}}function s(){var t=0,e=new Q(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){t.port2.postMessage(0)}}function c(){return function(){setTimeout(a,1)}}function a(){for(var t=0;G>t;t+=2){var e=X[t],n=X[t+1];e(n),X[t]=void 0,X[t+1]=void 0}G=0}function f(){try{var t=require,e=t("vertx");return U=e.runOnLoop||e.runOnContext,i()}catch(n){return c()}}function l(t,e){var n=this,r=n._state;if(r===et&&!t||r===nt&&!e)return this;var o=new this.constructor(p),i=n._result;if(r){var s=arguments[r-1];H(function(){C(r,o,s,i)})}else j(n,o,t,e);return o}function h(t){var e=this;if(t&&"object"==typeof t&&t.constructor===e)return t;var n=new e(p);return g(n,t),n}function p(){}function _(){return new TypeError("You cannot resolve a promise with itself")}function v(){return new TypeError("A promises callback cannot return that same promise.")}function d(t){try{return t.then}catch(e){return rt.error=e,rt}}function y(t,e,n,r){try{t.call(e,n,r)}catch(o){return o}}function m(t,e,n){H(function(t){var r=!1,o=y(n,e,function(n){r||(r=!0,e!==n?g(t,n):E(t,n))},function(e){r||(r=!0,S(t,e))},"Settle: "+(t._label||" unknown promise"));!r&&o&&(r=!0,S(t,o))},t)}function w(t,e){e._state===et?E(t,e._result):e._state===nt?S(t,e._result):j(e,void 0,function(e){g(t,e)},function(e){S(t,e)})}function b(t,n,r){n.constructor===t.constructor&&r===Z&&constructor.resolve===$?w(t,n):r===rt?S(t,rt.error):void 0===r?E(t,n):e(r)?m(t,n,r):E(t,n)}function g(e,n){e===n?S(e,_()):t(n)?b(e,n,d(n)):E(e,n)}function A(t){t._onerror&&t._onerror(t._result),T(t)}function E(t,e){t._state===tt&&(t._result=e,t._state=et,0!==t._subscribers.length&&H(T,t))}function S(t,e){t._state===tt&&(t._state=nt,t._result=e,H(A,t))}function j(t,e,n,r){var o=t._subscribers,i=o.length;t._onerror=null,o[i]=e,o[i+et]=n,o[i+nt]=r,0===i&&t._state&&H(T,t)}function T(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r,o,i=t._result,s=0;ss;s++)j(r.resolve(t[s]),void 0,e,n);return o}function Y(t){var e=this,n=new e(p);return S(n,t),n}function q(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function F(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function D(t){this._id=ct++,this._state=void 0,this._result=void 0,this._subscribers=[],p!==t&&("function"!=typeof t&&q(),this instanceof D?M(this,t):F())}function K(t,e){this._instanceConstructor=t,this.promise=new t(p),Array.isArray(e)?(this._input=e,this.length=e.length,this._remaining=e.length,this._result=new Array(this.length),0===this.length?E(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&E(this.promise,this._result))):S(this.promise,this._validationError())}function L(){var t;if("undefined"!=typeof global)t=global;else if("undefined"!=typeof self)t=self;else try{t=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var n=t.Promise;(!n||"[object Promise]"!==Object.prototype.toString.call(n.resolve())||n.cast)&&(t.Promise=at)}var N;N=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)};var U,W,z,B=N,G=0,H=function(t,e){X[G]=t,X[G+1]=e,G+=2,2===G&&(W?W(a):z())},I="undefined"!=typeof window?window:void 0,J=I||{},Q=J.MutationObserver||J.WebKitMutationObserver,R="undefined"!=typeof process&&"[object process]"==={}.toString.call(process),V="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,X=new Array(1e3);z=R?o():Q?s():V?u():void 0===I&&"function"==typeof require?f():c();var Z=l,$=h,tt=void 0,et=1,nt=2,rt=new P,ot=new P,it=O,st=k,ut=Y,ct=0,at=D;D.all=it,D.race=st,D.resolve=$,D.reject=ut,D._setScheduler=n,D._setAsap=r,D._asap=H,D.prototype={constructor:D,then:Z,"catch":function(t){return this.then(null,t)}};var ft=K;K.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},K.prototype._enumerate=function(){for(var t=this.length,e=this._input,n=0;this._state===tt&&t>n;n++)this._eachEntry(e[n],n)},K.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===$){var o=d(t);if(o===Z&&t._state!==tt)this._settledAt(t._state,e,t._result);else if("function"!=typeof o)this._remaining--,this._result[e]=t;else if(n===at){var i=new n(p);b(i,t,o),this._willSettleAt(i,e)}else this._willSettleAt(new n(function(e){e(t)}),e)}else this._willSettleAt(r(t),e)},K.prototype._settledAt=function(t,e,n){var r=this.promise;r._state===tt&&(this._remaining--,t===nt?S(r,n):this._result[e]=n),0===this._remaining&&E(r,this._result)},K.prototype._willSettleAt=function(t,e){var n=this;j(t,void 0,function(t){n._settledAt(et,e,t)},function(t){n._settledAt(nt,e,t)})};var lt=L,ht={Promise:at,polyfill:lt};"function"==typeof define&&define.amd?define(function(){return ht}):"undefined"!=typeof module&&module.exports?module.exports=ht:"undefined"!=typeof this&&(this.ES6Promise=ht),lt()}).call(this); -------------------------------------------------------------------------------- /src/bower_components/es6-promise/test/es6-promise.min.js: -------------------------------------------------------------------------------- 1 | (function(){"use strict";function t(t){return"function"==typeof t||"object"==typeof t&&null!==t}function e(t){return"function"==typeof t}function n(t){W=t}function r(t){H=t}function o(){return function(){process.nextTick(a)}}function i(){return function(){U(a)}}function s(){var t=0,e=new Q(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){t.port2.postMessage(0)}}function c(){return function(){setTimeout(a,1)}}function a(){for(var t=0;G>t;t+=2){var e=X[t],n=X[t+1];e(n),X[t]=void 0,X[t+1]=void 0}G=0}function f(){try{var t=require,e=t("vertx");return U=e.runOnLoop||e.runOnContext,i()}catch(n){return c()}}function l(t,e){var n=this,r=n._state;if(r===et&&!t||r===nt&&!e)return this;var o=new this.constructor(p),i=n._result;if(r){var s=arguments[r-1];H(function(){C(r,o,s,i)})}else j(n,o,t,e);return o}function h(t){var e=this;if(t&&"object"==typeof t&&t.constructor===e)return t;var n=new e(p);return g(n,t),n}function p(){}function _(){return new TypeError("You cannot resolve a promise with itself")}function v(){return new TypeError("A promises callback cannot return that same promise.")}function d(t){try{return t.then}catch(e){return rt.error=e,rt}}function y(t,e,n,r){try{t.call(e,n,r)}catch(o){return o}}function m(t,e,n){H(function(t){var r=!1,o=y(n,e,function(n){r||(r=!0,e!==n?g(t,n):E(t,n))},function(e){r||(r=!0,S(t,e))},"Settle: "+(t._label||" unknown promise"));!r&&o&&(r=!0,S(t,o))},t)}function w(t,e){e._state===et?E(t,e._result):e._state===nt?S(t,e._result):j(e,void 0,function(e){g(t,e)},function(e){S(t,e)})}function b(t,n,r){n.constructor===t.constructor&&r===Z&&constructor.resolve===$?w(t,n):r===rt?S(t,rt.error):void 0===r?E(t,n):e(r)?m(t,n,r):E(t,n)}function g(e,n){e===n?S(e,_()):t(n)?b(e,n,d(n)):E(e,n)}function A(t){t._onerror&&t._onerror(t._result),T(t)}function E(t,e){t._state===tt&&(t._result=e,t._state=et,0!==t._subscribers.length&&H(T,t))}function S(t,e){t._state===tt&&(t._state=nt,t._result=e,H(A,t))}function j(t,e,n,r){var o=t._subscribers,i=o.length;t._onerror=null,o[i]=e,o[i+et]=n,o[i+nt]=r,0===i&&t._state&&H(T,t)}function T(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r,o,i=t._result,s=0;ss;s++)j(r.resolve(t[s]),void 0,e,n);return o}function Y(t){var e=this,n=new e(p);return S(n,t),n}function q(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function F(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function D(t){this._id=ct++,this._state=void 0,this._result=void 0,this._subscribers=[],p!==t&&("function"!=typeof t&&q(),this instanceof D?M(this,t):F())}function K(t,e){this._instanceConstructor=t,this.promise=new t(p),Array.isArray(e)?(this._input=e,this.length=e.length,this._remaining=e.length,this._result=new Array(this.length),0===this.length?E(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&E(this.promise,this._result))):S(this.promise,this._validationError())}function L(){var t;if("undefined"!=typeof global)t=global;else if("undefined"!=typeof self)t=self;else try{t=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var n=t.Promise;(!n||"[object Promise]"!==Object.prototype.toString.call(n.resolve())||n.cast)&&(t.Promise=at)}var N;N=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)};var U,W,z,B=N,G=0,H=function(t,e){X[G]=t,X[G+1]=e,G+=2,2===G&&(W?W(a):z())},I="undefined"!=typeof window?window:void 0,J=I||{},Q=J.MutationObserver||J.WebKitMutationObserver,R="undefined"!=typeof process&&"[object process]"==={}.toString.call(process),V="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,X=new Array(1e3);z=R?o():Q?s():V?u():void 0===I&&"function"==typeof require?f():c();var Z=l,$=h,tt=void 0,et=1,nt=2,rt=new P,ot=new P,it=O,st=k,ut=Y,ct=0,at=D;D.all=it,D.race=st,D.resolve=$,D.reject=ut,D._setScheduler=n,D._setAsap=r,D._asap=H,D.prototype={constructor:D,then:Z,"catch":function(t){return this.then(null,t)}};var ft=K;K.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},K.prototype._enumerate=function(){for(var t=this.length,e=this._input,n=0;this._state===tt&&t>n;n++)this._eachEntry(e[n],n)},K.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===$){var o=d(t);if(o===Z&&t._state!==tt)this._settledAt(t._state,e,t._result);else if("function"!=typeof o)this._remaining--,this._result[e]=t;else if(n===at){var i=new n(p);b(i,t,o),this._willSettleAt(i,e)}else this._willSettleAt(new n(function(e){e(t)}),e)}else this._willSettleAt(r(t),e)},K.prototype._settledAt=function(t,e,n){var r=this.promise;r._state===tt&&(this._remaining--,t===nt?S(r,n):this._result[e]=n),0===this._remaining&&E(r,this._result)},K.prototype._willSettleAt=function(t,e){var n=this;j(t,void 0,function(t){n._settledAt(et,e,t)},function(t){n._settledAt(nt,e,t)})};var lt=L,ht={Promise:at,polyfill:lt};"function"==typeof define&&define.amd?define(function(){return ht}):"undefined"!=typeof module&&module.exports?module.exports=ht:"undefined"!=typeof this&&(this.ES6Promise=ht),lt()}).call(this); -------------------------------------------------------------------------------- /src/bower_components/es6-promise/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rsvp.js Tests 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/bower_components/es6-promise/test/mocha.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | body { 4 | margin:0; 5 | } 6 | 7 | #mocha { 8 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | margin: 60px 50px; 10 | } 11 | 12 | #mocha ul, 13 | #mocha li { 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | #mocha ul { 19 | list-style: none; 20 | } 21 | 22 | #mocha h1, 23 | #mocha h2 { 24 | margin: 0; 25 | } 26 | 27 | #mocha h1 { 28 | margin-top: 15px; 29 | font-size: 1em; 30 | font-weight: 200; 31 | } 32 | 33 | #mocha h1 a { 34 | text-decoration: none; 35 | color: inherit; 36 | } 37 | 38 | #mocha h1 a:hover { 39 | text-decoration: underline; 40 | } 41 | 42 | #mocha .suite .suite h1 { 43 | margin-top: 0; 44 | font-size: .8em; 45 | } 46 | 47 | #mocha .hidden { 48 | display: none; 49 | } 50 | 51 | #mocha h2 { 52 | font-size: 12px; 53 | font-weight: normal; 54 | cursor: pointer; 55 | } 56 | 57 | #mocha .suite { 58 | margin-left: 15px; 59 | } 60 | 61 | #mocha .test { 62 | margin-left: 15px; 63 | overflow: hidden; 64 | } 65 | 66 | #mocha .test.pending:hover h2::after { 67 | content: '(pending)'; 68 | font-family: arial, sans-serif; 69 | } 70 | 71 | #mocha .test.pass.medium .duration { 72 | background: #c09853; 73 | } 74 | 75 | #mocha .test.pass.slow .duration { 76 | background: #b94a48; 77 | } 78 | 79 | #mocha .test.pass::before { 80 | content: '✓'; 81 | font-size: 12px; 82 | display: block; 83 | float: left; 84 | margin-right: 5px; 85 | color: #00d6b2; 86 | } 87 | 88 | #mocha .test.pass .duration { 89 | font-size: 9px; 90 | margin-left: 5px; 91 | padding: 2px 5px; 92 | color: #fff; 93 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 94 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 95 | box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 96 | -webkit-border-radius: 5px; 97 | -moz-border-radius: 5px; 98 | -ms-border-radius: 5px; 99 | -o-border-radius: 5px; 100 | border-radius: 5px; 101 | } 102 | 103 | #mocha .test.pass.fast .duration { 104 | display: none; 105 | } 106 | 107 | #mocha .test.pending { 108 | color: #0b97c4; 109 | } 110 | 111 | #mocha .test.pending::before { 112 | content: '◦'; 113 | color: #0b97c4; 114 | } 115 | 116 | #mocha .test.fail { 117 | color: #c00; 118 | } 119 | 120 | #mocha .test.fail pre { 121 | color: black; 122 | } 123 | 124 | #mocha .test.fail::before { 125 | content: '✖'; 126 | font-size: 12px; 127 | display: block; 128 | float: left; 129 | margin-right: 5px; 130 | color: #c00; 131 | } 132 | 133 | #mocha .test pre.error { 134 | color: #c00; 135 | max-height: 300px; 136 | overflow: auto; 137 | } 138 | 139 | /** 140 | * (1): approximate for browsers not supporting calc 141 | * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border) 142 | * ^^ seriously 143 | */ 144 | #mocha .test pre { 145 | display: block; 146 | float: left; 147 | clear: left; 148 | font: 12px/1.5 monaco, monospace; 149 | margin: 5px; 150 | padding: 15px; 151 | border: 1px solid #eee; 152 | max-width: 85%; /*(1)*/ 153 | max-width: calc(100% - 42px); /*(2)*/ 154 | word-wrap: break-word; 155 | border-bottom-color: #ddd; 156 | -webkit-border-radius: 3px; 157 | -webkit-box-shadow: 0 1px 3px #eee; 158 | -moz-border-radius: 3px; 159 | -moz-box-shadow: 0 1px 3px #eee; 160 | border-radius: 3px; 161 | } 162 | 163 | #mocha .test h2 { 164 | position: relative; 165 | } 166 | 167 | #mocha .test a.replay { 168 | position: absolute; 169 | top: 3px; 170 | right: 0; 171 | text-decoration: none; 172 | vertical-align: middle; 173 | display: block; 174 | width: 15px; 175 | height: 15px; 176 | line-height: 15px; 177 | text-align: center; 178 | background: #eee; 179 | font-size: 15px; 180 | -moz-border-radius: 15px; 181 | border-radius: 15px; 182 | -webkit-transition: opacity 200ms; 183 | -moz-transition: opacity 200ms; 184 | transition: opacity 200ms; 185 | opacity: 0.3; 186 | color: #888; 187 | } 188 | 189 | #mocha .test:hover a.replay { 190 | opacity: 1; 191 | } 192 | 193 | #mocha-report.pass .test.fail { 194 | display: none; 195 | } 196 | 197 | #mocha-report.fail .test.pass { 198 | display: none; 199 | } 200 | 201 | #mocha-report.pending .test.pass, 202 | #mocha-report.pending .test.fail { 203 | display: none; 204 | } 205 | #mocha-report.pending .test.pass.pending { 206 | display: block; 207 | } 208 | 209 | #mocha-error { 210 | color: #c00; 211 | font-size: 1.5em; 212 | font-weight: 100; 213 | letter-spacing: 1px; 214 | } 215 | 216 | #mocha-stats { 217 | position: fixed; 218 | top: 15px; 219 | right: 10px; 220 | font-size: 12px; 221 | margin: 0; 222 | color: #888; 223 | z-index: 1; 224 | } 225 | 226 | #mocha-stats .progress { 227 | float: right; 228 | padding-top: 0; 229 | } 230 | 231 | #mocha-stats em { 232 | color: black; 233 | } 234 | 235 | #mocha-stats a { 236 | text-decoration: none; 237 | color: inherit; 238 | } 239 | 240 | #mocha-stats a:hover { 241 | border-bottom: 1px solid #eee; 242 | } 243 | 244 | #mocha-stats li { 245 | display: inline-block; 246 | margin: 0 5px; 247 | list-style: none; 248 | padding-top: 11px; 249 | } 250 | 251 | #mocha-stats canvas { 252 | width: 40px; 253 | height: 40px; 254 | } 255 | 256 | #mocha code .comment { color: #ddd; } 257 | #mocha code .init { color: #2f6fad; } 258 | #mocha code .string { color: #5890ad; } 259 | #mocha code .keyword { color: #8a6343; } 260 | #mocha code .number { color: #2f6fad; } 261 | 262 | @media screen and (max-device-width: 480px) { 263 | #mocha { 264 | margin: 60px 0; 265 | } 266 | 267 | #mocha #stats { 268 | position: absolute; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/bower_components/es6-promise/test/worker.js: -------------------------------------------------------------------------------- 1 | importScripts('es6-promise.js'); 2 | new ES6Promise.Promise(function(resolve, reject) { 3 | self.onmessage = function (e) { 4 | if (e.data === 'ping') { 5 | resolve('pong'); 6 | } else { 7 | reject(new Error('wrong message')); 8 | } 9 | }; 10 | }).then(function (result) { 11 | self.postMessage(result); 12 | }, function (err){ 13 | setTimeout(function () { 14 | throw err; 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/bower_components/polymer/LICENSE.txt: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 The Polymer Authors. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /src/bower_components/polymer/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polymer", 3 | "version": "1.2.3", 4 | "main": [ 5 | "polymer.html" 6 | ], 7 | "license": "http://polymer.github.io/LICENSE.txt", 8 | "ignore": [ 9 | "/.*", 10 | "/test/", 11 | "gen-changelog.sh" 12 | ], 13 | "authors": [ 14 | "The Polymer Authors (http://polymer.github.io/AUTHORS.txt)" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/Polymer/polymer.git" 19 | }, 20 | "dependencies": { 21 | "webcomponentsjs": "^0.7.18" 22 | }, 23 | "devDependencies": { 24 | "web-component-tester": "*" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /src/bower_components/webcomponentsjs/MutationObserver.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 4 | * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5 | * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6 | * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7 | * Code distributed by Google as part of the polymer project is also 8 | * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9 | */ 10 | // @version 0.7.20 11 | "undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,r=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};r.prototype={set:function(t,r){var i=t[this.name];return i&&i[0]===t?i[1]=r:e(t,this.name,{value:[t,r],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=r}(),function(e){function t(e){N.push(e),O||(O=!0,b(i))}function r(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function i(){O=!1;var e=N;N=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var r=e.takeRecords();n(e),r.length&&(e.callback_(r,e),t=!0)}),t&&i()}function n(e){e.nodes_.forEach(function(t){var r=p.get(t);r&&r.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function a(e,t){for(var r=e;r;r=r.parentNode){var i=p.get(r);if(i)for(var n=0;n0){var n=r[i-1],a=l(n,e);if(a)return void(r[i-1]=a)}else t(this.observer);r[i]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=p.get(e);t||p.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=p.get(e),r=0;r` tags in the main document block the loading of such imports. This is to ensure the imports have loaded and any registered elements in them have been upgraded. 79 | 80 | The webcomponents.js and webcomponents-lite.js polyfills parse element definitions and handle their upgrade asynchronously. If prematurely fetching the element from the DOM before it has an opportunity to upgrade, you'll be working with an `HTMLUnknownElement`. 81 | 82 | For these situations (or when you need an approximate replacement for the Polymer 0.5 `polymer-ready` behavior), you can use the `WebComponentsReady` event as a signal before interacting with the element. The criteria for this event to fire is all Custom Elements with definitions registered by the time HTML Imports available at load time have loaded have upgraded. 83 | 84 | ```js 85 | window.addEventListener('WebComponentsReady', function(e) { 86 | // imports are loaded and elements have been registered 87 | console.log('Components are ready'); 88 | }); 89 | ``` 90 | 91 | ## Known Issues 92 | 93 | * [Custom element's constructor property is unreliable](#constructor) 94 | * [Contenteditable elements do not trigger MutationObserver](#contentedit) 95 | * [ShadowCSS: :host-context(...):host(...) doesn't work](#hostcontext) 96 | * [execCommand isn't supported under Shadow DOM](#execcommand) 97 | 98 | ### Custom element's constructor property is unreliable 99 | See [#215](https://github.com/webcomponents/webcomponentsjs/issues/215) for background. 100 | 101 | In Safari and IE, instances of Custom Elements have a `constructor` property of `HTMLUnknownElementConstructor` and `HTMLUnknownElement`, respectively. It's unsafe to rely on this property for checking element types. 102 | 103 | It's worth noting that `customElement.__proto__.__proto__.constructor` is `HTMLElementPrototype` and that the prototype chain isn't modified by the polyfills(onto `ElementPrototype`, etc.) 104 | 105 | ### Contenteditable elements do not trigger MutationObserver 106 | Using the MutationObserver polyfill, it isn't possible to monitor mutations of an element marked `contenteditable`. 107 | See [the mailing list](https://groups.google.com/forum/#!msg/polymer-dev/LHdtRVXXVsA/v1sGoiTYWUkJ) 108 | 109 | ### ShadowCSS: :host-context(...):host(...) doesn't work 110 | See [#16](https://github.com/webcomponents/webcomponentsjs/issues/16) for background. 111 | 112 | Under the shadow DOM polyfill, rules like: 113 | ``` 114 | :host-context(.foo):host(.bar) {...} 115 | ``` 116 | don't work, despite working under native Shadow DOM. The solution is to use `polyfill-next-selector` like: 117 | 118 | ``` 119 | polyfill-next-selector { content: '.foo :host.bar, :host.foo.bar'; } 120 | ``` 121 | 122 | ### execCommand and contenteditable isn't supported under Shadow DOM 123 | See [#212](https://github.com/webcomponents/webcomponentsjs/issues/212) 124 | 125 | `execCommand`, and `contenteditable` aren't supported under the ShadowDOM polyfill, with commands that insert or remove nodes being especially prone to failure. 126 | -------------------------------------------------------------------------------- /src/bower_components/webcomponentsjs/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webcomponentsjs", 3 | "main": "webcomponents.js", 4 | "version": "0.7.20", 5 | "homepage": "http://webcomponents.org", 6 | "authors": [ 7 | "The Polymer Authors" 8 | ], 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/webcomponents/webcomponentsjs.git" 12 | }, 13 | "keywords": [ 14 | "webcomponents" 15 | ], 16 | "license": "BSD", 17 | "ignore": [], 18 | "devDependencies": { 19 | "web-component-tester": "^4.0.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/bower_components/webcomponentsjs/build.log: -------------------------------------------------------------------------------- 1 | BUILD LOG 2 | --------- 3 | Build Time: 2015-12-15T17:26:55-0800 4 | 5 | NODEJS INFORMATION 6 | ================== 7 | nodejs: v4.2.3 8 | gulp: 3.9.0 9 | gulp-audit: 1.0.0 10 | gulp-concat: 2.6.0 11 | gulp-header: 1.7.1 12 | gulp-uglify: 1.5.1 13 | run-sequence: 1.1.5 14 | web-component-tester: 4.0.2 15 | 16 | REPO REVISIONS 17 | ============== 18 | webcomponentsjs: 5f1284369eb57e94ca4e88d5d71ceaeb65d1c569 19 | 20 | BUILD HASHES 21 | ============ 22 | CustomElements.js: 2e3f1d24da1b907cc328b6276f336aed65a07f11 23 | CustomElements.min.js: a762e3c191cc8d40094650317eace96595ddb2f7 24 | HTMLImports.js: 83d1d2df9b1fc622712e33e61b42a11445699b6b 25 | HTMLImports.min.js: a3f8245b26035a6452acadba2d95a5f2653b357e 26 | MutationObserver.js: 830bdcc25cdc392491d29b350ca077308f3baf4d 27 | MutationObserver.min.js: 73cbbfa3d44343e0286c133d7d5139dedd9a9765 28 | ShadowDOM.js: fa039071d7f15dba05d9cea27267d048cfddd1bf 29 | ShadowDOM.min.js: 975f1950c1347181b067a2d989ca1d8fafe854db 30 | webcomponents-lite.js: ab4d2adff62906fe3860fed00ee2584146b0f162 31 | webcomponents-lite.min.js: e59f28a7684cb56c84f83e411b13f0167c19898e 32 | webcomponents.js: 4881aa5c0dc2d730053ea701b11566cc04464738 33 | webcomponents.min.js: 305994efdabba100244df45ae6d86894bc69cd53 -------------------------------------------------------------------------------- /src/bower_components/webcomponentsjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webcomponents.js", 3 | "version": "0.7.20", 4 | "description": "webcomponents.js", 5 | "main": "webcomponents.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/webcomponents/webcomponentsjs.git" 12 | }, 13 | "author": "The Polymer Authors", 14 | "license": "BSD-3-Clause", 15 | "bugs": { 16 | "url": "https://github.com/webcomponents/webcomponentsjs/issues" 17 | }, 18 | "scripts": { 19 | "test": "wct" 20 | }, 21 | "homepage": "http://webcomponents.org", 22 | "devDependencies": { 23 | "gulp": "^3.8.8", 24 | "gulp-audit": "^1.0.0", 25 | "gulp-concat": "^2.4.1", 26 | "gulp-header": "^1.1.1", 27 | "gulp-uglify": "^1.0.1", 28 | "run-sequence": "^1.0.1", 29 | "web-component-tester": "^4.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/dom_modules/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /src/dom_modules/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /src/dom_modules/jsonld.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | 27 | -------------------------------------------------------------------------------- /src/dom_modules/result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 68 | 108 | 109 | -------------------------------------------------------------------------------- /src/dom_modules/slide-share.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/extension/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/extension/common.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | /* reset */ 4 | body, div, p, ul, ol, li, dl, dt, dd, 5 | h1, h2, h3, h4, h5, h6, table, th, td, img, form, figure { 6 | margin: 0; 7 | padding: 0; 8 | } 9 | ul, ol { 10 | list-style: none; 11 | } 12 | *, 13 | *:before, 14 | *:after { 15 | box-sizing: border-box; 16 | } 17 | h1, h2, h3, h4, h5, h6, small { 18 | font-size: inherit; 19 | } 20 | img, input, select, textarea, button, svg, canvas, object { 21 | vertical-align: middle; 22 | } 23 | input, select, textarea, button { 24 | /*outline: 0;*/ 25 | background-color: inherit; 26 | color: inherit; 27 | } 28 | input, textarea { 29 | line-height: inherit; 30 | } 31 | input, select, textarea, button, h1, h2, h3, h4, h5, h6 { 32 | font-size: 1rem; 33 | font-family: inherit; 34 | } 35 | 36 | input:disabled, select:disabled, textarea:disabled, button:disabled { 37 | opacity: 0.6; 38 | } 39 | label { 40 | cursor: pointer; 41 | } 42 | html { 43 | font-size: 13px; 44 | line-height: 1.4; 45 | font-family: Roboto, 'Noto', 'Helvetica Neue', Helvetica, Arial, sans-serif; 46 | background-color: #F9F9F9; 47 | color: #5f5f5f; 48 | } 49 | 50 | /* anchors */ 51 | a:link, 52 | a:visited { 53 | color: #359C62; 54 | text-decoration: none; 55 | } 56 | a:hover, 57 | a:active { 58 | text-decoration: underline; 59 | } 60 | 61 | /* clearfix */ 62 | .cf:after { 63 | content: ''; 64 | display: block; 65 | clear: both; 66 | } 67 | 68 | .header { 69 | display: flex; 70 | justify-content: space-between; 71 | padding: calc(2% + 8px) 4%; 72 | background: #F9F9F9; 73 | z-index: 1000; 74 | align-items: center; 75 | -webkit-transition: 0.2s ease; 76 | -moz-transition: 0.2s ease; 77 | -ms-transition: 0.2s ease; 78 | -o-transition: 0.2s ease; 79 | transition: 0.2s ease; 80 | } 81 | .header-heading { 82 | display: flex; 83 | font-size: 26px; 84 | font-weight: normal; 85 | /* padding-left: 54px; */ 86 | /* text-indent: -54px; */ 87 | line-height: 1.05; 88 | align-items: center; 89 | flex: 1 0 33.333%; 90 | } 91 | .header-heading img { 92 | margin-right: 8px; 93 | width: 46px; 94 | } 95 | .header-nav { 96 | flex: 1 0 66.666%; 97 | padding-left: 4%; 98 | } 99 | .header-nav-list { 100 | margin: 0; 101 | display: flex; 102 | flex-wrap: wrap; 103 | justify-content: flex-end; 104 | } 105 | .header-nav-list > li { 106 | flex-shrink: 0; 107 | } 108 | .header-nav-list > li + li { 109 | margin-left: 3%; 110 | } 111 | .header-nav-list > li > a { 112 | display: flex; 113 | flex-wrap: nowrap; 114 | align-items: center; 115 | padding: 2px 4px 2px 0; 116 | white-space: nowrap; 117 | } 118 | .header-nav img { 119 | margin-right: 6px; 120 | height: 25px; 121 | width: auto; 122 | } 123 | 124 | .footer { 125 | padding: calc(2% + 5px) 4%; 126 | background: #333333; 127 | color: white; 128 | min-height: 210px; 129 | } 130 | 131 | /* module */ 132 | input[type="text"] { 133 | background-color: white; 134 | border: 1px solid #DDD; 135 | } 136 | input[type="radio"], 137 | input[type="checkbox"] { 138 | margin-top: 0; 139 | margin-bottom: 0; 140 | } 141 | button, 142 | .button { 143 | background-color: #FAFAFA; 144 | color: inherit !important; 145 | border: 0; 146 | font-size: 11px; 147 | padding: 4px; 148 | cursor: pointer; 149 | text-align: center; 150 | text-decoration: none !important; 151 | border-radius: 4px; 152 | border-bottom: 2px solid #CECECE; 153 | box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2); 154 | } 155 | .note-list { 156 | counter-reset: note-list; 157 | } 158 | .note-list > li { 159 | text-indent: -1.1em; 160 | padding-left: 1.1em; 161 | } 162 | .note-list > li:before { 163 | counter-increment: note-list; 164 | content: counter(note-list,decimal) ', '; 165 | } 166 | 167 | .is-hidden { 168 | display: none !important; 169 | } 170 | 171 | @media (max-width: 640px) { 172 | .header { 173 | flex-direction: column; 174 | } 175 | .header > * { 176 | flex-basis: auto; 177 | } 178 | .header-nav { 179 | padding-left: 0; 180 | margin-top: 10px; 181 | } 182 | .header-nav-list { 183 | justify-content: center; 184 | flex-wrap: nowrap; 185 | } 186 | .header-nav-list > li + li > a { 187 | padding-left: 0; 188 | } 189 | .header-nav-list > li > a { 190 | padding: 2px 10px; 191 | } 192 | } -------------------------------------------------------------------------------- /src/extension/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var STYLEV = STYLEV || {}; 4 | 5 | STYLEV.COMMON = { 6 | 7 | execute: function() { 8 | var that = STYLEV.COMMON; 9 | 10 | that.setParameters(); 11 | that.bindEvents(); 12 | that.showWelcomeMsg(); 13 | that.setNameOfOS(); 14 | }, 15 | 16 | setParameters: function() { 17 | var that = STYLEV.COMMON; 18 | 19 | }, 20 | 21 | bindEvents: function() { 22 | var that = STYLEV.COMMON; 23 | 24 | }, 25 | 26 | showWelcomeMsg: function() { 27 | var that = STYLEV.COMMON; 28 | 29 | console.info('%cWelcome to Style Validator!', 'font-size: 18px; color: #1F9E0D; line-height: 1.7;'); 30 | }, 31 | 32 | setNameOfOS: function() { 33 | var typeOfOS; 34 | var appVersion = navigator.appVersion; 35 | if (appVersion.indexOf("Mac") !== -1 ) { 36 | typeOfOS = "is-mac"; 37 | } else if (appVersion.indexOf("PowerPC") !== -1 ) { 38 | typeOfOS = "is-mac"; 39 | } else if (appVersion.indexOf("Win") !== -1 ) { 40 | typeOfOS = "is-win"; 41 | } 42 | document.documentElement.classList.add(typeOfOS); 43 | } 44 | }; 45 | 46 | STYLEV.COMMON.execute(); -------------------------------------------------------------------------------- /src/extension/data/README.md: -------------------------------------------------------------------------------- 1 | # To start develop 2 | 3 | #### 1. git clone 4 | 5 | ``` 6 | git clone https://github.com/Style-Validator/Style-Validator.git 7 | ``` 8 | 9 | #### 2. npm Install 10 | 11 | ``` 12 | npm install 13 | ``` 14 | 15 | #### 3. import directory to chrome 16 | 17 | ![](../img/extension-import.png) 18 | 19 | 20 | # How to add new rule 21 | 22 | #### 1. gulp 23 | 24 | ``` 25 | node app.js 26 | ``` 27 | 28 | #### 2. access edit page via web server 29 | 30 | http://localhost:8001/extension/options.html 31 | 32 | 33 | #### 3. add new rule and save 34 | 35 | ![](../img/edit-page.png) 36 | 37 | 38 | # Format of Style Rules 39 | 40 | ## Format 41 | 42 | ```json 43 | [ 44 | { 45 | "base-styles": { 46 | }, 47 | "error-style": { 48 | }, 49 | "warning-style": { 50 | }, 51 | "parent-error-style": { 52 | }, 53 | "parent-warning-style": { 54 | }, 55 | "psuedo-before-error-style": { 56 | }, 57 | "psuedo-before-warning-style": { 58 | }, 59 | "psuedo-after-error-style": { 60 | }, 61 | "psuedo-after-warning-style": { 62 | }, 63 | "referenceURL": "https://developer.mozilla.org/en/docs/Web/CSS/float", 64 | "message": "here is error message" 65 | } 66 | ] 67 | ``` 68 | 69 | ## Basic Pattern 70 | 71 | ### Base Style and Warning Styles 72 | 73 | ```json 74 | [ 75 | { 76 | "base-styles": { 77 | "display": "inline" 78 | }, 79 | "warning-style": { 80 | "margin-top": "!0",//same with "non-0" 81 | "margin-bottom": "non-0"//same with !0 82 | } 83 | } 84 | ] 85 | ``` 86 | 87 | ### Simplest Pattern 88 | 89 | ```json 90 | [ 91 | { 92 | "error-style": {//warning-style is another pattern 93 | "z-index": "under-0" 94 | } 95 | } 96 | ] 97 | ``` 98 | 99 | 100 | ## Feature 101 | 102 | ### Base Rules is AND search 103 | 104 | ```json 105 | [ 106 | { 107 | "base-styles": { 108 | //AND 109 | "display": "table", 110 | "border-collapse": "collapse" 111 | }, 112 | "error-style": { 113 | "padding": "over-0" 114 | } 115 | } 116 | ] 117 | ``` 118 | ### Error or Warning Styles is OR search 119 | 120 | ```json 121 | [ 122 | { 123 | "base-styles": { 124 | "float": "!left" 125 | }, 126 | "warning-style": { 127 | "margin-top": "!0",//same with "non-0" 128 | "margin-bottom": "non-0"//same with !0 129 | } 130 | } 131 | ] 132 | ``` 133 | 134 | ### "default" keyword can be used (Not CSS Value, Original Value) 135 | 136 | ```json 137 | [ 138 | { 139 | "base-styles": { 140 | //Not User Agent Style sheet 141 | "float": "!default"//same with "non-default" 142 | }, 143 | "warning-style": [ 144 | //User Agent Style sheet 145 | { "margin-top": "default" } 146 | ] 147 | } 148 | ] 149 | ``` 150 | 151 | ### "OR operator ||" can be used in the value 152 | 153 | ```json 154 | [ 155 | { 156 | "base-styles": { 157 | "float": "left||right"//OR 158 | }, 159 | "warning-style": { 160 | "margin-top": "non-0" 161 | } 162 | } 163 | ] 164 | ``` 165 | 166 | 167 | #### Otherwise, to be Array the value is same. 168 | 169 | ```json 170 | [ 171 | { 172 | "base-styles": { 173 | "float": ["left", "right"]//OR 174 | }, 175 | "warning-style": { 176 | "margin-top": "non-0" 177 | } 178 | } 179 | ] 180 | ``` 181 | 182 | ## Original value keyword 183 | 184 | ### not default (detect not defining) 185 | 186 | ```json 187 | "error-styles" { 188 | "float": "!default" 189 | } 190 | 191 | "error-styles" { 192 | "float": "non-default" 193 | } 194 | ``` 195 | 196 | ### not 0 197 | 198 | ```json 199 | "error-styles" { 200 | "margin-top": "!0" 201 | } 202 | 203 | "error-styles" { 204 | "margin-top": "non-0" 205 | } 206 | ``` 207 | ### over 0 208 | 209 | ```json 210 | "error-styles" { 211 | "padding-top": "over-0" 212 | } 213 | ``` 214 | ### under 0 215 | 216 | ```json 217 | "error-styles" { 218 | "padding-top": "under-0" 219 | } 220 | ``` 221 | 222 | ## Bad Pattern 223 | 224 | ### Only Base Style 225 | 226 | ```json 227 | [ 228 | { 229 | "base-styles": { 230 | "display": "block" 231 | } 232 | } 233 | ] 234 | ``` 235 | -------------------------------------------------------------------------------- /src/extension/data/special-kw-vals.json: -------------------------------------------------------------------------------- 1 | [ 2 | "default", 3 | "!default", 4 | "inherit", 5 | "!inherit", 6 | "0", 7 | "!0", 8 | "over-0", 9 | "under-0" 10 | ] -------------------------------------------------------------------------------- /src/extension/data/tags-all.json: -------------------------------------------------------------------------------- 1 | [ 2 | "a", 3 | "abbr", 4 | "acronym", 5 | "address", 6 | "applet", 7 | "area", 8 | "article", 9 | "aside", 10 | "audio", 11 | "b", 12 | "base", 13 | "basefont", 14 | "bdi", 15 | "bdo", 16 | "big", 17 | "blockquote", 18 | "body", 19 | "br", 20 | "button", 21 | "canvas", 22 | "caption", 23 | "center", 24 | "cite", 25 | "code", 26 | "col", 27 | "colgroup", 28 | "datalist", 29 | "dd", 30 | "del", 31 | "details", 32 | "dfn", 33 | "dialog", 34 | "dir", 35 | "div", 36 | "dl", 37 | "dt", 38 | "em", 39 | "embed", 40 | "fieldset", 41 | "figcaption", 42 | "figure", 43 | "font", 44 | "footer", 45 | "form", 46 | "frame", 47 | "frameset", 48 | "h1", 49 | "h2", 50 | "h3", 51 | "h4", 52 | "h5", 53 | "h6", 54 | "head", 55 | "header", 56 | "hr", 57 | "html", 58 | "i", 59 | "iframe", 60 | "img", 61 | "input", 62 | "ins", 63 | "kbd", 64 | "keygen", 65 | "label", 66 | "legend", 67 | "li", 68 | "link", 69 | "main", 70 | "map", 71 | "mark", 72 | "menu", 73 | "menuitem", 74 | "meta", 75 | "meter", 76 | "nav", 77 | "noframes", 78 | "nobr", 79 | "noscript", 80 | "object", 81 | "ol", 82 | "optgroup", 83 | "option", 84 | "output", 85 | "p", 86 | "param", 87 | "pre", 88 | "picture", 89 | "progress", 90 | "q", 91 | "rp", 92 | "rt", 93 | "ruby", 94 | "s", 95 | "samp", 96 | "script", 97 | "section", 98 | "select", 99 | "small", 100 | "source", 101 | "span", 102 | "strike", 103 | "strong", 104 | "shadow", 105 | "style", 106 | "sub", 107 | "summary", 108 | "sup", 109 | "table", 110 | "tbody", 111 | "td", 112 | "textarea", 113 | "tfoot", 114 | "th", 115 | "thead", 116 | "time", 117 | "template", 118 | "title", 119 | "tr", 120 | "track", 121 | "tt", 122 | "u", 123 | "ul", 124 | "var", 125 | "video", 126 | "wbr", 127 | "svg" 128 | ] -------------------------------------------------------------------------------- /src/extension/data/tags-empty.json: -------------------------------------------------------------------------------- 1 | [ 2 | "area", 3 | "img", 4 | "hr", 5 | "br", 6 | "wbr" 7 | ] -------------------------------------------------------------------------------- /src/extension/data/tags-filter.json: -------------------------------------------------------------------------------- 1 | [ 2 | "script", 3 | "style", 4 | "option", 5 | "template", 6 | "source", 7 | "svg" 8 | ] -------------------------------------------------------------------------------- /src/extension/data/tags-replaced-element.json: -------------------------------------------------------------------------------- 1 | [ 2 | "img", 3 | "canvas", 4 | "iframe", 5 | "object", 6 | "embed", 7 | "video", 8 | "svg", 9 | "button", 10 | "math", 11 | "audio", 12 | "input", 13 | "select", 14 | "textarea" 15 | ] -------------------------------------------------------------------------------- /src/extension/data/tags-table-children.json: -------------------------------------------------------------------------------- 1 | [ 2 | "tbody", 3 | "thead", 4 | "tfoot", 5 | "tr", 6 | "th", 7 | "td", 8 | "caption", 9 | "colgroup", 10 | "col" 11 | ] -------------------------------------------------------------------------------- /src/extension/devtools-detect.js: -------------------------------------------------------------------------------- 1 | /*! 2 | devtools-detect 3 | Detect if DevTools is open 4 | https://github.com/sindresorhus/devtools-detect 5 | by Sindre Sorhus 6 | MIT License 7 | */ 8 | (function () { 9 | 'use strict'; 10 | var devtools = {open: false}; 11 | var threshold = 160; 12 | var emitEvent = function (state) { 13 | window.dispatchEvent(new CustomEvent('devtoolschange', { 14 | detail: { 15 | open: state 16 | } 17 | })); 18 | }; 19 | 20 | if ((window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized) || window.outerWidth - window.innerWidth > threshold || 21 | window.outerHeight - window.innerHeight > threshold) { 22 | if (!devtools.open) { 23 | emitEvent(true); 24 | } 25 | devtools.open = true; 26 | } else { 27 | if (devtools.open) { 28 | emitEvent(false); 29 | } 30 | 31 | devtools.open = false; 32 | } 33 | 34 | if (typeof module !== 'undefined' && module.exports) { 35 | module.exports = devtools; 36 | } else { 37 | window.devtools = devtools; 38 | } 39 | })(); 40 | 41 | window.devtools.open; -------------------------------------------------------------------------------- /src/extension/devtools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/extension/devtools.js: -------------------------------------------------------------------------------- 1 | //TODO: create panel page 2 | //chrome.devtools.panels.create( 3 | // "Style Validator", 4 | // "../img/style-validator.logo.png", 5 | // "panel.html", 6 | // function(panel) { 7 | // console.log("hello from callback"); 8 | // } 9 | //); 10 | 11 | var port; 12 | var isValidated = false; 13 | 14 | var executionString = 15 | "STYLEV.inspect = inspect;" + 16 | "STYLEV.$0 = $0;" + 17 | "var bindInspect = function(){" + 18 | "STYLEV.CHROME_DEVTOOLS.execute(function(targetElem) {" + 19 | "STYLEV.inspect(targetElem || STYLEV.$0);" + 20 | "});" + 21 | "};" + 22 | "STYLEV.VALIDATOR.updateOptions().then(function() {" + 23 | "console.groupEnd();" + 24 | "console.group('Style Validator: Executed by Chrome Extension from DevTools Page');" + 25 | "STYLEV.VALIDATOR.execute(bindInspect);" + 26 | "});"; 27 | 28 | var executionTimerString = 'STYLEV.VALIDATOR.setExecutionTimer();'; 29 | 30 | var scriptSetting = { useContentScriptContext: true }; 31 | 32 | var executeWithInspect = function() { 33 | chrome.devtools.inspectedWindow.eval(executionString, scriptSetting); 34 | }; 35 | 36 | var executeWhenModified = function(resource) { 37 | 38 | //TODO: handle `resource` arguments? 39 | if(isValidated) { 40 | chrome.devtools.inspectedWindow.eval(executionTimerString, scriptSetting); 41 | console.log(resource.url); 42 | } 43 | }; 44 | 45 | var connect2BackgroundPage = function() { 46 | 47 | port = chrome.runtime.connect({ 48 | name: "devtoolsPage" 49 | }); 50 | 51 | port.postMessage({ 52 | name: 'sendTabId', 53 | tabId: chrome.devtools.inspectedWindow.tabId 54 | }); 55 | 56 | port.onMessage.addListener(function(message) { 57 | if(message.name == "executeWithInspect") { 58 | executeWithInspect(); 59 | } 60 | if(message.name == "getIsValidated") { 61 | isValidated = message.isValidated; 62 | } 63 | 64 | }); 65 | }; 66 | 67 | //Create connection to background page 68 | connect2BackgroundPage(); 69 | 70 | //When reloaded 71 | chrome.devtools.network.onNavigated.addListener(function(url) { 72 | 73 | connect2BackgroundPage(); 74 | 75 | //When resources is modified 76 | chrome.devtools.inspectedWindow.onResourceContentCommitted.removeListener(executeWhenModified); 77 | chrome.devtools.inspectedWindow.onResourceContentCommitted.addListener(executeWhenModified); 78 | 79 | //When resources is added 80 | //chrome.devtools.inspectedWindow.onResourceAdded.removeListener(executeWhenModified); 81 | //chrome.devtools.inspectedWindow.onResourceAdded.addListener(executeWhenModified); 82 | }); 83 | 84 | //When resources is modified 85 | chrome.devtools.inspectedWindow.onResourceContentCommitted.addListener(executeWhenModified); 86 | 87 | //When resources is added 88 | //chrome.devtools.inspectedWindow.onResourceAdded.addListener(executeWhenModified); -------------------------------------------------------------------------------- /src/extension/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/extension/favicon.ico -------------------------------------------------------------------------------- /src/extension/google-analytics-options.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 4 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 5 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 6 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 7 | 8 | if(location.protocol === 'chrome-extension:') { 9 | ga('create', 'UA-53227157-5', 'auto'); 10 | ga('set', 'checkProtocolTask', null); 11 | ga('send', 'pageview', '/options.html'); 12 | } else { 13 | ga('create', 'UA-53227157-3', 'auto'); 14 | ga('send', 'pageview'); 15 | } 16 | 17 | window.addEventListener('error', function(error) { 18 | 19 | var errorString = ''; 20 | 21 | errorString += error.message || ''; 22 | if(error.filename) { 23 | errorString += '('; 24 | errorString += error.filename || ''; 25 | errorString += error.lineno ? ':' + error.lineno : ''; 26 | errorString += error.colno ? ':' + error.colno : ''; 27 | errorString += ')'; 28 | } 29 | if(error.stack) { 30 | errorString += '('; 31 | errorString += error.stack; 32 | errorString += ')'; 33 | } 34 | 35 | ga('send', 'event', 'error', 'execute', errorString, location.href); 36 | ga('send', 'exception', { 37 | 'exDescription': errorString, 38 | 'exFatal': true 39 | }); 40 | }); -------------------------------------------------------------------------------- /src/extension/google-analytics.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (function() { 4 | 5 | if(!hasAnalyticsGoogle()) { 6 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 7 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 8 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 9 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 10 | } 11 | 12 | ga('create', 'UA-53227157-5', 'auto', {'name': 'styleValidator'}); 13 | 14 | var src = document.currentScript.src; 15 | var splitSrc = src.split('?'); 16 | 17 | //Normal 18 | if(splitSrc.length <= 1) { 19 | 20 | ga('styleValidator.send', 'event', 'button', 'execute', 'validation', 1); 21 | 22 | //Other 23 | } else { 24 | 25 | var queryStrings = splitSrc.pop(); 26 | var queryStringObj = parseQueryString(queryStrings); 27 | 28 | if(queryStringObj.error) { 29 | ga('styleValidator.send', 'event', 'error', 'execute', queryStringObj.error, location.href); 30 | ga('styleValidator.send', 'exception',{ 31 | 'exDescription': queryStringObj.error, 32 | 'exFatal': true 33 | }); 34 | } 35 | } 36 | 37 | function parseQueryString(path) { 38 | 39 | var queryStrings = path.split('?').pop(); 40 | var queryStringArray = decodeURIComponent(queryStrings).split('&'); 41 | var queryStringObj = {}; 42 | 43 | for(var i = 0, len = queryStringArray.length; i < len; i++) { 44 | var queryString = queryStringArray[i].split('='); 45 | var key = queryString[0]; 46 | var value = queryString[1]; 47 | queryStringObj[key] = value; 48 | } 49 | 50 | return queryStringObj; 51 | } 52 | 53 | function hasAnalyticsGoogle(){ 54 | var scripts = document.querySelectorAll('script'); 55 | var len = scripts.length; 56 | for (var i = 0; i < len; i++) { 57 | var scriptSrc = scripts[i].src; 58 | if (scriptSrc.indexOf('google-analytics.com/analytics.js') > -1) { 59 | return true; 60 | } 61 | } 62 | return false; 63 | } 64 | }()); -------------------------------------------------------------------------------- /src/extension/iconmonstr-cube-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-cube-2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-download-2-icon-active.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-download-2-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-edit-8-icon-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-edit-8-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-help-6-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-link-4-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-link-5-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-link-icon-gray.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-magnifier-6.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-menu-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-menu-2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-minus-2-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-plus-2-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-refresh-3-icon-active.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-refresh-3-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-responsive.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-responsive3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-responsive4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-save-5-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-save-icon-active.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-save-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-selection-10-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-undo-4-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-upload-4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-view-6.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-x-mark-3-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/iconmonstr-x-mark-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "Style-Validator", 4 | "version": "0.6.1.6", 5 | "description": "A CSS Validator that can check the combination of styles and elements after browser rendering.", 6 | "icons": { 7 | "16": "./style-validator.logo_16x16.png", 8 | "48": "./style-validator.logo_200x200.png", 9 | "128": "./style-validator.logo_200x200.png" 10 | }, 11 | "browser_action": { 12 | "default_icon": { 13 | "19": "./style-validator.logo_200x200.png", 14 | "38": "./style-validator.logo_200x200.png" 15 | }, 16 | "default_title": "Style Validator" 17 | }, 18 | "author": "Igari Takeharu", 19 | "background": { 20 | "page": "./background.html", 21 | "persistent": false 22 | }, 23 | "content_scripts": [ 24 | { 25 | "run_at": "document_idle", 26 | "matches": [ 27 | "https://*/*", 28 | "http://*/*" 29 | ], 30 | "css": [ 31 | "./style-validator-for-elements.css" 32 | ], 33 | "js": [ 34 | "./specificity.js", 35 | "./style-validator.js" 36 | ] 37 | } 38 | ], 39 | "devtools_page": "./devtools.html", 40 | "options_page": "./options.html", 41 | "options_ui": { 42 | "page": "./options.html", 43 | "chrome_style": false 44 | }, 45 | "commands": { 46 | "toggle-validation": { 47 | "suggested_key": { 48 | "default": "Ctrl+Shift+I", 49 | "mac": "Command+Shift+I" 50 | }, 51 | "description": "Toggle Validation" 52 | } 53 | }, 54 | "homepage_url": "https://style-validator.io/", 55 | "offline_enabled": true, 56 | "short_name": "Style Validator", 57 | "web_accessible_resources": [ 58 | "data/rules.json", 59 | "data/tags-all.json", 60 | "data/tags-empty.json", 61 | "data/tags-replaced-element.json", 62 | "data/tags-filter.json", 63 | "data/special-kw-vals.json", 64 | "iconmonstr-refresh-3-icon.svg", 65 | "iconmonstr-refresh-3-icon-active.svg", 66 | "iconmonstr-minus-2-icon.svg", 67 | "iconmonstr-x-mark-icon.svg", 68 | "iconmonstr-plus-2-icon.svg", 69 | "iconmonstr-link-4-icon.svg", 70 | "iconmonstr-link-5-icon.svg", 71 | "iconmonstr-responsive.svg", 72 | "iconmonstr-edit-8-icon-white.svg", 73 | "style-validator.logo.black.svg", 74 | "style-validator-for-console.css", 75 | "specificity.js", 76 | "webcomponents.min.js", 77 | "google-analytics.js" 78 | ], 79 | "permissions": [ 80 | "activeTab", 81 | "webNavigation", 82 | "tabs", 83 | "https://*/*", 84 | "http://*/*", 85 | "storage", 86 | "management" 87 | ], 88 | "content_security_policy": "script-src 'self' https://www.google-analytics.com; object-src 'self'" 89 | } 90 | -------------------------------------------------------------------------------- /src/extension/panel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Sample

7 | 8 | 9 | -------------------------------------------------------------------------------- /src/extension/panel.js: -------------------------------------------------------------------------------- 1 | console.log("panel.js"); -------------------------------------------------------------------------------- /src/extension/popup.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | img { 4 | vertical-align: middle; 5 | } 6 | 7 | body { 8 | width: 400px; 9 | } 10 | h1 img { 11 | margin-top: -3px; 12 | } 13 | ul { 14 | list-style: none; 15 | padding-left: 0; 16 | } 17 | input[type="text"] { 18 | margin-left: 20px; 19 | width: 300px; 20 | } 21 | label { 22 | display: block; 23 | margin-bottom: 5px; 24 | } 25 | li + li { 26 | margin-top: 10px; 27 | } 28 | footer { 29 | text-align: right; 30 | } 31 | header { 32 | position: relative; 33 | } 34 | header button { 35 | position: absolute; 36 | top: 0; 37 | right: 0; 38 | bottom: 0; 39 | margin: auto; 40 | height: 35px; 41 | width: 80px; 42 | font-size: 15px; 43 | } -------------------------------------------------------------------------------- /src/extension/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 | 11 |

Style Validator

12 |
13 |
14 |
15 |
16 |

Mutation Observer

17 |
    18 |
  • 19 |
20 |
21 |
22 |

Execution

23 |
    24 |
  • 25 |
26 |
27 |
28 |

Animation

29 |
    30 |
  • 31 |
32 |
33 |
34 |

Define Scope by Selector

35 |
    36 |
  • 37 | 38 | 39 |
  • 40 |
  • 41 | 42 | 43 |
  • 44 |
45 |
46 |
47 |
48 |
49 | 50 | 61 | 62 | -------------------------------------------------------------------------------- /src/extension/popup.js: -------------------------------------------------------------------------------- 1 | var STYLEV = STYLEV || {}; 2 | 3 | STYLEV.popup = { 4 | execute: function() { 5 | 6 | var that = this; 7 | that.setParameters(); 8 | that.bindEvents(); 9 | that.modifyValue(); 10 | }, 11 | setParameters: function() { 12 | 13 | var that = this; 14 | 15 | that.validateTrigger = document.querySelector('#validate-trigger'); 16 | that.formParts = document.querySelectorAll('.option-form-parts'); 17 | that.isFirst = true; 18 | that.options = {}; 19 | }, 20 | bindEvents: function() { 21 | 22 | var that = this; 23 | 24 | that.validateTrigger.addEventListener('click', that.executeValidate, false); 25 | 26 | for(var i = 0, len = that.formParts.length; i < len; i++) { 27 | 28 | var target = that.formParts[i]; 29 | 30 | target.addEventListener('keyup', that.modifyValue.bind(that), false); 31 | target.addEventListener('blur', that.modifyValue.bind(that), false); 32 | target.addEventListener('change', that.modifyValue.bind(that), false); 33 | } 34 | }, 35 | modifyValue: function() { 36 | 37 | var that = this; 38 | 39 | for(var i = 0, len = that.formParts.length; i < len; i++) { 40 | 41 | var target = that.formParts[i]; 42 | var type = target.type; 43 | var id = target.id; 44 | var checkbox = type === 'radio' || type === 'checkbox'; 45 | var textbox = type === 'text'; 46 | var isChecked = checkbox ? target.checked : false; 47 | var name = target.name; 48 | var value = target.value; 49 | 50 | if(localStorage.getItem(id) !== null && that.isFirst) { 51 | 52 | if(checkbox) { 53 | 54 | target.checked = localStorage.getItem(id) === 'true'; 55 | } 56 | if(textbox) { 57 | 58 | target.value = localStorage.getItem(id); 59 | } 60 | 61 | } else { 62 | 63 | if(checkbox) { 64 | 65 | that.options[id] = isChecked; 66 | localStorage.setItem(id, isChecked); 67 | } 68 | if(textbox) { 69 | 70 | that.options[id] = value; 71 | localStorage.setItem(id, value); 72 | } 73 | } 74 | 75 | 76 | if(id === 'scopeSelectors' || id === 'ignoreSelectors') { 77 | 78 | var defineBox = document.querySelector('#' + id + 'Text'); 79 | defineBox.disabled = !isChecked; 80 | } 81 | } 82 | 83 | if(!that.isFirst) { 84 | chrome.storage.sync.set({'options': that.options}); 85 | } else { 86 | that.isFirst = false; 87 | } 88 | }, 89 | executeValidate: function() { 90 | 91 | chrome.tabs.executeScript({ 92 | code: "STYLEV.CHROME_EXTENSION.execute();" 93 | }); 94 | } 95 | }; 96 | STYLEV.popup.execute(); -------------------------------------------------------------------------------- /src/extension/specificity.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculates the specificity of CSS selectors 3 | * http://www.w3.org/TR/css3-selectors/#specificity 4 | * 5 | * Returns an array of objects with the following properties: 6 | * - selector: the input 7 | * - specificity: e.g. 0,1,0,0 8 | * - parts: array with details about each part of the selector that counts towards the specificity 9 | */ 10 | var SPECIFICITY = (function() { 11 | var calculate, 12 | calculateSingle; 13 | 14 | calculate = function(input) { 15 | var selectors, 16 | selector, 17 | i, 18 | len, 19 | results = []; 20 | 21 | // Separate input by commas 22 | selectors = input.split(','); 23 | 24 | for (i = 0, len = selectors.length; i < len; i += 1) { 25 | selector = selectors[i]; 26 | if (selector.length > 0) { 27 | results.push(calculateSingle(selector)); 28 | } 29 | } 30 | 31 | return results; 32 | }; 33 | 34 | // Calculate the specificity for a selector by dividing it into simple selectors and counting them 35 | calculateSingle = function(input) { 36 | var selector = input, 37 | findMatch, 38 | typeCount = { 39 | 'a': 0, 40 | 'b': 0, 41 | 'c': 0 42 | }, 43 | parts = [], 44 | // The following regular expressions assume that selectors matching the preceding regular expressions have been removed 45 | attributeRegex = /(\[[^\]]+\])/g, 46 | idRegex = /(#[^\s\+>~\.\[:]+)/g, 47 | classRegex = /(\.[^\s\+>~\.\[:]+)/g, 48 | pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi, 49 | // A regex for pseudo classes with brackets - :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-type(), :lang() 50 | pseudoClassWithBracketsRegex = /(:[\w-]+\([^\)]*\))/gi, 51 | // A regex for other pseudo classes, which don't have brackets 52 | pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g, 53 | elementRegex = /([^\s\+>~\.\[:]+)/g; 54 | 55 | // Find matches for a regular expression in a string and push their details to parts 56 | // Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements 57 | findMatch = function(regex, type) { 58 | var matches, i, len, match, index, length; 59 | if (regex.test(selector)) { 60 | matches = selector.match(regex); 61 | for (i = 0, len = matches.length; i < len; i += 1) { 62 | typeCount[type] += 1; 63 | match = matches[i]; 64 | index = selector.indexOf(match); 65 | length = match.length; 66 | parts.push({ 67 | selector: match, 68 | type: type, 69 | index: index, 70 | length: length 71 | }); 72 | // Replace this simple selector with whitespace so it won't be counted in further simple selectors 73 | selector = selector.replace(match, Array(length + 1).join(' ')); 74 | } 75 | } 76 | }; 77 | 78 | // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument 79 | (function() { 80 | var regex = /:not\(([^\)]*)\)/g; 81 | if (regex.test(selector)) { 82 | selector = selector.replace(regex, ' $1 '); 83 | } 84 | }()); 85 | 86 | // Remove anything after a left brace in case a user has pasted in a rule, not just a selector 87 | (function() { 88 | var regex = /{[^]*/gm, 89 | matches, i, len, match; 90 | if (regex.test(selector)) { 91 | matches = selector.match(regex); 92 | for (i = 0, len = matches.length; i < len; i += 1) { 93 | match = matches[i]; 94 | selector = selector.replace(match, Array(match.length + 1).join(' ')); 95 | } 96 | } 97 | }()); 98 | 99 | // Add attribute selectors to parts collection (type b) 100 | findMatch(attributeRegex, 'b'); 101 | 102 | // Add ID selectors to parts collection (type a) 103 | findMatch(idRegex, 'a'); 104 | 105 | // Add class selectors to parts collection (type b) 106 | findMatch(classRegex, 'b'); 107 | 108 | // Add pseudo-element selectors to parts collection (type c) 109 | findMatch(pseudoElementRegex, 'c'); 110 | 111 | // Add pseudo-class selectors to parts collection (type b) 112 | findMatch(pseudoClassWithBracketsRegex, 'b'); 113 | findMatch(pseudoClassRegex, 'b'); 114 | 115 | // Remove universal selector and separator characters 116 | selector = selector.replace(/[\*\s\+>~]/g, ' '); 117 | 118 | // Remove any stray dots or hashes which aren't attached to words 119 | // These may be present if the user is live-editing this selector 120 | selector = selector.replace(/[#\.]/g, ' '); 121 | 122 | // The only things left should be element selectors (type c) 123 | findMatch(elementRegex, 'c'); 124 | 125 | // Order the parts in the order they appear in the original selector 126 | // This is neater for external apps to deal with 127 | parts.sort(function(a, b) { 128 | return a.index - b.index; 129 | }); 130 | 131 | return { 132 | selector: input, 133 | specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(), 134 | parts: parts 135 | }; 136 | }; 137 | 138 | return { 139 | calculate: calculate 140 | }; 141 | }()); 142 | 143 | // Export for Node JS 144 | if (typeof exports !== 'undefined') { 145 | exports.calculate = SPECIFICITY.calculate; 146 | } 147 | -------------------------------------------------------------------------------- /src/extension/style-validator-for-console.bak: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | :host * { 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | :host *, 9 | :host *:before, 10 | :host *:after { 11 | box-sizing: border-box; 12 | } 13 | 14 | :host > * { 15 | font-size: 11px; 16 | font-family: Menlo, monospace, sans-serif; 17 | text-align: left; 18 | text-indent: 0; 19 | line-height: 1.7; 20 | color: #333333; 21 | } 22 | 23 | :host > *, 24 | :host > *:before, 25 | :host > *:after { 26 | -webkit-box-sizing: border-box; 27 | -moz-box-sizing: border-box; 28 | box-sizing: border-box; 29 | } 30 | 31 | :host { 32 | position: fixed; 33 | right: 0; 34 | bottom: 0; 35 | left: 0; 36 | z-index: 10000000000; 37 | background: rgba(255, 255, 255, 0.8); 38 | display: flex; 39 | flex-direction: column; 40 | align-items: stretch; 41 | max-height: 40%; 42 | } 43 | :host .stylev-console-header { 44 | display: flex; 45 | flex-wrap: wrap; 46 | overflow: hidden; 47 | justify-content: space-between; 48 | align-items: center; 49 | background-color: #EEE; 50 | border-top: 1px solid #A3A3A3; 51 | border-bottom: 1px solid #CCC; 52 | border-right-width: 0; 53 | border-left-width: 0; 54 | flex: 0 0 auto; 55 | cursor: ns-resize; 56 | } 57 | :host .stylev-console-header:active { 58 | border-style: dashed; 59 | } 60 | :host .stylev-console-header > * { 61 | display: flex; 62 | align-self: stretch; 63 | align-items: center; 64 | flex: 0 1 auto; 65 | min-height: 28px; 66 | border-bottom: 1px dotted #CCCCCC; 67 | margin-bottom: -1px; 68 | padding: 3px 0; 69 | } 70 | :host .stylev-console-heading { 71 | justify-content: center; 72 | flex-basis: 32px; 73 | } 74 | :host .stylev-console-heading-logo { 75 | display: flex; 76 | } 77 | :host .stylev-console-heading-logo-image { 78 | width: 20px; 79 | height: 20px; 80 | margin: auto; 81 | } 82 | :host .stylev-console-connection { 83 | padding-left: 6px; 84 | padding-right: 10px; 85 | background-position: 5px center; 86 | background-repeat: no-repeat; 87 | background-size: 20px auto; 88 | color: white; 89 | line-height: 1.1; 90 | flex-shrink: 0; 91 | } 92 | :host .stylev-console-connection:empty { 93 | display: none; 94 | } 95 | :host .stylev-console-connection-image { 96 | width: 18px; 97 | height: 18px; 98 | vertical-align: -18%; 99 | margin-right: 5px; 100 | } 101 | :host .stylev-console-connected { 102 | background-color: #008000; 103 | } 104 | :host .stylev-console-disconnected { 105 | background-color: #FF0000; 106 | } 107 | @media (max-width: 640px) { 108 | :host .stylev-console-connection { 109 | position: relative; 110 | width: 30px; 111 | color: transparent; 112 | text-indent: 100%; 113 | white-space: nowrap; 114 | overflow: hidden; 115 | padding: 0; 116 | background-position: center center; 117 | } 118 | :host .stylev-console-connection-image { 119 | position: absolute; 120 | top: 0; 121 | right: 0; 122 | bottom: 0; 123 | left: 0; 124 | margin: auto; 125 | } 126 | } 127 | 128 | :host .stylev-console-counter { 129 | flex-grow: 1; 130 | padding-right: 10px; 131 | line-height: 1.2; 132 | } 133 | :host .stylev-console-mediaqueries { 134 | padding: 3px 6px; 135 | background-color: #f9f9f9; 136 | } 137 | :host .stylev-console-mediaqueries-image { 138 | width: 18px; 139 | height: auto; 140 | margin-right: 4px; 141 | } 142 | :host .stylev-console-mediaqueries-text { 143 | line-height: 1.4; 144 | } 145 | :host .stylev-console-mediaqueries-image:only-child { 146 | margin-right: 0; 147 | } 148 | :host .stylev-console-buttons { 149 | margin-left: auto; 150 | } 151 | :host .stylev-console-buttons > a { 152 | display: flex; 153 | justify-content: center; 154 | position: relative; 155 | width: 28px; 156 | color: inherit; 157 | text-align: center; 158 | text-decoration: none; 159 | font-size: 20px; 160 | align-items: center; 161 | align-self: stretch; 162 | } 163 | :host .stylev-console-buttons > a > img { 164 | } 165 | :host .stylev-console-refresh-button { 166 | } 167 | :host .stylev-console-refresh-button img { 168 | width: 22px; 169 | height: 22px; 170 | } 171 | :host .stylev-console-refresh-button-image { 172 | } 173 | :host .stylev-console-refresh-button-image-active { 174 | } 175 | :host .stylev-console-refresh-button-active .stylev-console-refresh-button-image-active { 176 | -webkit-animation: active-button 1s infinite; 177 | -o-animation: active-button 1s infinite; 178 | animation: active-button 1s infinite; 179 | } 180 | :host .stylev-console-refresh-count { 181 | position: absolute; 182 | top: 2px; 183 | right: 0; 184 | bottom: 0; 185 | left: 0; 186 | text-align: center; 187 | font-size: 8px; 188 | line-height: 1.5; 189 | height: 1.5em; 190 | margin: auto; 191 | } 192 | @keyframes active-button { 193 | 0% { 194 | -webkit-transform: scale(1); 195 | } 196 | 100% { 197 | -webkit-transform: scale(1.25); 198 | } 199 | } 200 | @-webkit-keyframes active-button { 201 | 0% { 202 | -webkit-transform: scale(1); 203 | } 204 | 100% { 205 | -webkit-transform: scale(1.25); 206 | } 207 | } 208 | 209 | 210 | :host .stylev-console-close-button { 211 | } 212 | :host .stylev-console-close-button-image { 213 | width: 16px; 214 | height: 16px; 215 | } 216 | :host .stylev-console-minimize-button { 217 | } 218 | :host .stylev-console-minimize-button-image { 219 | width: 16px; 220 | height: 16px; 221 | } 222 | :host .stylev-console-normalize-button { 223 | } 224 | :host .stylev-console-normalize-button-image { 225 | width: 16px; 226 | height: 16px; 227 | } 228 | :host .stylev-console-body { 229 | flex: 1 1 auto; 230 | overflow-y: auto; 231 | } 232 | :host .stylev-console-list { 233 | list-style: none; 234 | line-height: 1.5; 235 | } 236 | :host .stylev-console-list > li { 237 | /*display: flex;*/ 238 | /*justify-content: space-between;*/ 239 | /*align-items: center;*/ 240 | padding: 3px 0 2px; 241 | } 242 | :host .stylev-console-list > li + li { 243 | border-top: 1px solid #EEE; 244 | } 245 | :host .stylev-console-list-anchor { 246 | display: block; 247 | padding: 0 5px; 248 | color: inherit !important; 249 | text-decoration: none !important; 250 | cursor: pointer; 251 | text-indent: calc(-1.2em - 10px); 252 | padding-left: calc(1.2em + 10px); 253 | } 254 | :host .stylev-console-list-anchor:before { 255 | text-indent: 0; 256 | margin-left: 5px; 257 | } 258 | :host .stylev-console-list-anchor:hover { 259 | text-decoration: underline; 260 | } 261 | :host .stylev-console-list-ids { 262 | float: right; 263 | padding: 0 5px; 264 | display: flex; 265 | text-align: right; 266 | flex: 0 1 auto; 267 | } 268 | :host .stylev-console-list-stylevid { 269 | margin-left: 5px; 270 | color: #808080 !important; 271 | } 272 | :host .stylev-console-list-stylevid:before { 273 | content: 'stylevid:' 274 | } 275 | :host .stylev-console-list-ruleid { 276 | margin-left: 5px; 277 | color: #666 !important; 278 | } 279 | :host .stylev-console-list-ruleid:before { 280 | content: 'Rule:' 281 | } 282 | :host .stylev-console-list > li.stylev-trigger-error { 283 | border-color: #FFD8D7; 284 | } 285 | :host .stylev-console-list > li.stylev-trigger-warning { 286 | border-color: #FFDD9E; 287 | } 288 | :host .stylev-console-list > li.stylev-trigger-error { 289 | background-color: #FFEFEF; 290 | color: #FF0000; 291 | } 292 | :host .stylev-console-list > li.stylev-trigger-error > a:before { 293 | content: '×'; 294 | display: inline-block; 295 | width: 1.2em; 296 | height: 1.2em; 297 | line-height: 1.2; 298 | margin-right: 0.5em; 299 | vertical-align: middle; 300 | background: #FF0000; 301 | border-radius: 100%; 302 | color: #FFF; 303 | text-align: center; 304 | } 305 | :host .stylev-console-list > li.stylev-trigger-warning { 306 | background-color: #FFFBE5; 307 | color: #444444; 308 | } 309 | :host .stylev-console-list > li.stylev-trigger-warning > a:before { 310 | content: '!'; 311 | display: inline-block; 312 | width: 1.2em; 313 | height: 1.2em; 314 | line-height: 1.2; 315 | margin-right: 0.5em; 316 | vertical-align: middle; 317 | background: #F6BE00; 318 | border-radius: 50% 50% 0 0 / 100% 100% 0 0; 319 | color: #FFF; 320 | text-align: center; 321 | } 322 | :host .stylev-console-list > li.stylev-trigger-selected > a { 323 | font-weight: bold; 324 | } 325 | 326 | :host .stylev-console-perfect { 327 | display: flex; 328 | align-items: center; 329 | justify-content: center; 330 | } 331 | :host .stylev-console-perfect:after { 332 | content: 'Parfect!'; 333 | display: block; 334 | font-size: 38px; 335 | height: 50px; 336 | line-height: 50px; 337 | } 338 | 339 | :host .is-hidden { 340 | display: none !important; 341 | } -------------------------------------------------------------------------------- /src/extension/style-validator-for-elements.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | /************************************************************************************* 4 | Basic 5 | *************************************************************************************/ 6 | 7 | html { 8 | border-color: transparent; 9 | border-style: solid; 10 | border-top-width: 0; 11 | border-right-width: 0; 12 | border-bottom-width: 0; 13 | border-left-width: 0; 14 | } 15 | 16 | 17 | /************************************************************************************* 18 | デフォルトスタイルを取得用のiframe 19 | *************************************************************************************/ 20 | 21 | #stylev-dummy-iframe { 22 | visibility: hidden !important; 23 | position: fixed !important; 24 | top: 100% !important; 25 | right: 100% !important; 26 | z-index: -1 !important; 27 | pointer-events: none !important; 28 | } 29 | 30 | /************************************************************************************* 31 | JavaScriptで付加させるClass 32 | *************************************************************************************/ 33 | 34 | /* Warning */ 35 | 36 | .stylev-target-warning { 37 | outline-width: 5px; 38 | outline-style: solid; 39 | outline-color: #F6BE00; 40 | } 41 | .stylev-animation .stylev-target-warning { 42 | -webkit-animation: warning 1s infinite alternate; 43 | -moz-animation: warning 1s infinite alternate; 44 | animation: warning 1s infinite alternate; 45 | } 46 | 47 | @-webkit-keyframes warning { 48 | from { outline-color: rgba(0, 0, 0, 0); } 49 | to { outline-color: #F6BE00; } 50 | } 51 | @-moz-keyframes warning { 52 | from { outline-color: rgba(0, 0, 0, 0); } 53 | to { outline-color: #F6BE00; } 54 | } 55 | @keyframes warning { 56 | from { outline-color: rgba(0, 0, 0, 0); } 57 | to { outline-color: #F6BE00; } 58 | } 59 | 60 | .stylev-target-error { 61 | outline-width: 5px; 62 | outline-style: solid; 63 | outline-color: #FF0000; 64 | } 65 | .stylev-animation .stylev-target-error { 66 | -webkit-animation: error 1s infinite alternate; 67 | -moz-animation: error 1s infinite alternate; 68 | animation: error 1s infinite alternate; 69 | } 70 | 71 | /* Error */ 72 | 73 | @-webkit-keyframes error { 74 | from { outline-color: #ee6c71; } 75 | to { outline-color: rgba(0, 0, 0, 0); } 76 | } 77 | 78 | @-moz-keyframes error { 79 | from { outline-color: #ee6c71; } 80 | to { outline-color: rgba(0, 0, 0, 0); } 81 | } 82 | 83 | @keyframes error { 84 | from { outline-color: #ee6c71; } 85 | to { outline-color: rgba(0, 0, 0, 0); } 86 | } 87 | 88 | /* Error and Warning */ 89 | 90 | .stylev-target-error.stylev-target-warning { 91 | outline-width: 5px; 92 | outline-style: solid; 93 | outline-color: #FF0000; 94 | } 95 | .stylev-animation .stylev-target-error.stylev-target-warning { 96 | -webkit-animation: errorAndWarning 1s infinite alternate; 97 | -moz-animation: errorAndWarning 1s infinite alternate; 98 | animation: errorAndWarning 1s infinite alternate; 99 | } 100 | 101 | @-webkit-keyframes errorAndWarning { 102 | from { outline-color: #FF0000; } 103 | to { outline-color: rgba(0, 0, 0, 0); } 104 | } 105 | 106 | @-moz-keyframes errorAndWarning { 107 | from { outline-color: #FF0000; } 108 | to { outline-color: rgba(0, 0, 0, 0); } 109 | } 110 | 111 | @keyframes errorAndWarning { 112 | from { outline-color: #FF0000; } 113 | to { outline-color: rgba(0, 0, 0, 0); } 114 | } 115 | 116 | .stylev-target-selected { 117 | outline-style: dashed; 118 | -webkit-animation: selected 1.5s infinite; 119 | -moz-animation: selected 1.5s infinite; 120 | animation: selected 1.5s infinite; 121 | } 122 | @-webkit-keyframes selected { 123 | 0% { outline-style: dashed; } 124 | 50% { outline-style: dotted; } 125 | } 126 | @-moz-keyframes selected { 127 | 0% { outline-style: dashed; } 128 | 50% { outline-style: dotted; } 129 | } 130 | @keyframes selected { 131 | 0% { outline-style: dashed; } 132 | 50% { outline-style: dotted; } 133 | } -------------------------------------------------------------------------------- /src/extension/style-validator.logo.black.svg: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /src/extension/style-validator.logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/extension/style-validator.logo.png -------------------------------------------------------------------------------- /src/extension/style-validator.logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/extension/style-validator.logo_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/extension/style-validator.logo_16x16.png -------------------------------------------------------------------------------- /src/extension/style-validator.logo_200x200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/extension/style-validator.logo_200x200.png -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/favicon.ico -------------------------------------------------------------------------------- /src/gif_animations/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/gif_animations/demo.gif -------------------------------------------------------------------------------- /src/img/GitHub-Mark-32px-lightgreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/bookmarkbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/bookmarkbar.png -------------------------------------------------------------------------------- /src/img/chromeWebStore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/chromeWebStore.png -------------------------------------------------------------------------------- /src/img/chrome_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/chrome_128x128.png -------------------------------------------------------------------------------- /src/img/css-prop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 16 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/img/edge_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/edge_128x128.png -------------------------------------------------------------------------------- /src/img/edit-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/edit-page.png -------------------------------------------------------------------------------- /src/img/extension-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/extension-import.png -------------------------------------------------------------------------------- /src/img/firefox_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/firefox_128x128.png -------------------------------------------------------------------------------- /src/img/html-tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/img/html-validator.logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/html-validator.logo.png -------------------------------------------------------------------------------- /src/img/iconmonstr-chart-19.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-cube-17.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-cube-18.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-edit-8-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-flask-7-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-help-3-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-link-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-note-19.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/iconmonstr-refresh-3-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/internet-explorer_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/internet-explorer_128x128.png -------------------------------------------------------------------------------- /src/img/js-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /src/img/macbook-pro-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/macbook-pro-retina.png -------------------------------------------------------------------------------- /src/img/opera_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/opera_128x128.png -------------------------------------------------------------------------------- /src/img/safari_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/safari_128x128.png -------------------------------------------------------------------------------- /src/img/screenshot-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/screenshot-console.png -------------------------------------------------------------------------------- /src/img/screenshot-rulepage.1280x800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/screenshot-rulepage.1280x800.png -------------------------------------------------------------------------------- /src/img/screenshot-rulepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/screenshot-rulepage.png -------------------------------------------------------------------------------- /src/img/screenshot-validator.1280x800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/screenshot-validator.1280x800.png -------------------------------------------------------------------------------- /src/img/screenshot-validator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/screenshot-validator.png -------------------------------------------------------------------------------- /src/img/style-validator.cover.1280x800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.cover.1280x800.png -------------------------------------------------------------------------------- /src/img/style-validator.cover.1400x560.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.cover.1400x560.png -------------------------------------------------------------------------------- /src/img/style-validator.cover.440x280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.cover.440x280.png -------------------------------------------------------------------------------- /src/img/style-validator.cover.920x680.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.cover.920x680.png -------------------------------------------------------------------------------- /src/img/style-validator.logo.nopadding.64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.logo.nopadding.64x64.png -------------------------------------------------------------------------------- /src/img/style-validator.logo.nopadding.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/style-validator.logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/style-validator.logo_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/src/img/style-validator.logo_128x128.png -------------------------------------------------------------------------------- /src/page/analytics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Style Validator - A Next CSS Validator - 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 75 | 76 |
77 |
78 |

References

79 |
80 |
81 | Analytics Page 82 | 83 |
84 |
85 | 86 | 87 | -------------------------------------------------------------------------------- /src/page/common.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | html, 4 | body, 5 | .wrapper { 6 | height: 100%; 7 | } 8 | 9 | .content-width { 10 | max-width: 1000px; 11 | margin-right: auto; 12 | margin-left: auto; 13 | padding: 4%; 14 | } 15 | .wrapper { 16 | display: flex; 17 | flex-flow: column nowrap; 18 | margin: 0 auto; 19 | } 20 | .main { 21 | flex: 1 0 auto; 22 | flex-flow: column nowrap; 23 | display: flex; 24 | } 25 | 26 | /*html:not(.is-fixed-header) .wrapper { 27 | padding-top: 0 !important; 28 | }*/ 29 | /* 30 | .is-fixed-header .header { 31 | position: fixed; 32 | top: 0; 33 | right: 0; 34 | left: 0; 35 | -webkit-box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1); 36 | -moz-box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1); 37 | box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1); 38 | } 39 | */ 40 | 41 | .kv-buttons-list { 42 | display: flex; 43 | justify-content: space-between; 44 | margin-top: 6%; 45 | margin-left: -10px; 46 | } 47 | .kv-buttons-list > li { 48 | flex: 1 1 50%; 49 | display: flex; 50 | padding-left: 10px; 51 | } 52 | .kv-buttons-list > li > a { 53 | display: flex; 54 | padding: 6px 12px; 55 | border: 1px solid transparent; 56 | text-decoration: none !important; 57 | -webkit-transition: 0.2s ease; 58 | -moz-transition: 0.2s ease; 59 | -ms-transition: 0.2s ease; 60 | -o-transition: 0.2s ease; 61 | transition: 0.2s ease; 62 | background-color: white; 63 | color: #359C62 !important; 64 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); 65 | flex: 1 0 100%; 66 | } 67 | .kv-buttons-list a:hover { 68 | border-color: rgb(49, 194, 92); 69 | } 70 | .kv-buttons-list a > img { 71 | margin-top: 10px; 72 | max-width: 100%; 73 | height: auto; 74 | } 75 | .kv-buttons-wrapper { 76 | flex: 1 1 auto; 77 | display: flex; 78 | flex-direction: column; 79 | justify-content: space-between; 80 | } 81 | .kv-buttons-wrapper > * { 82 | flex: 1 0 auto; 83 | } 84 | .kv-buttons-heading { 85 | margin-bottom: 5px; 86 | font-weight: normal; 87 | text-align: left; 88 | } 89 | .kv-buttons-image-wrapper img { 90 | max-width: 100%; 91 | width: 100%; 92 | height: auto; 93 | } 94 | .kv-buttons-caption { 95 | 96 | } 97 | 98 | .browser-support { 99 | display: flex; 100 | justify-content: flex-end; 101 | flex-wrap: wrap; 102 | } 103 | .browser-support > li.disabled { 104 | filter: url("data:image/svg+xml;utf8,#greyscale"); 105 | filter: gray; 106 | filter: grayscale(100%); 107 | -webkit-filter: grayscale(1); 108 | -webkit-filter: grayscale(100%); 109 | } 110 | .browser-support > li { 111 | /* float: right; */ 112 | } 113 | .browser-support > li + li { 114 | padding-left: 5px; 115 | } 116 | .browser-support > li img { 117 | width: 20px; 118 | height: auto; 119 | } 120 | .buttons-section { 121 | flex-basis: 380px; 122 | } 123 | .buttons-section + .buttons-section { 124 | margin-left: 2%; 125 | } 126 | .buttons-section-heading { 127 | margin-top: 0; 128 | font-size: 18px; 129 | font-weight: normal; 130 | text-align: center; 131 | margin-bottom: 10px; 132 | } 133 | #bookmarklet:after { 134 | content: 'Bookmark this link.'; 135 | display: none; 136 | color: #7C7D80 !important; 137 | } -------------------------------------------------------------------------------- /src/page/demo-by-rules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Simple Demo | Style Validator 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 109 | 110 | 111 |
112 |
113 |

Rules

114 |
115 |
116 |
    117 |
    118 |
    119 | 120 |
    121 |
    122 | 123 | 124 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/page/demo-simple.hbs: -------------------------------------------------------------------------------- 1 | {{#each this}} 2 |
  • 3 |
    4 |
    5 |

    {{title}}

    6 |
    7 |
    8 | 9 |
    10 |
    11 |
  • 12 | {{/each}} -------------------------------------------------------------------------------- /src/page/demo-simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Simple Demo | Style Validator 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 109 | 110 | 111 | 112 |
    113 |

    114 |
      115 |
    1. Get Style Validator (Chrome Extension)
    2. 116 |
    3. Click Bookmark Icon to start Style Validator
    4. 117 |
    5. Click the below Button
    6. 118 |
    119 |
    120 |
    121 | 122 |

    Style Validator can detect Risky Style

    123 | 124 | table-row with margin-top 125 |
    126 |
    127 |

    Style Validator can detect Risky Style by JavaScript

    128 |
    129 |

    table-cell has parent

    130 |
    131 |
    132 | 133 | 134 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/page/demo-simple.jsbin.embed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Simple Demo | Style Validator 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 111 | 112 | 113 | JS Bin on jsbin.com 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/page/demo.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | /* reset */ 4 | ul { 5 | list-style: none; 6 | } 7 | 8 | img { 9 | vertical-align: middle; 10 | } 11 | 12 | /* anchors */ 13 | a:link, 14 | a:visited { 15 | color: #359C62; 16 | text-decoration: none; 17 | } 18 | a:hover, 19 | a:active { 20 | text-decoration: underline; 21 | } 22 | 23 | html { 24 | font-family: Roboto, 'Noto', 'Helvetica Neue', Helvetica, Arial, sans-serif; 25 | } 26 | 27 | /* page style */ 28 | body { 29 | padding: 2vw 4vw; 30 | background: -webkit-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 31 | background: -moz-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 32 | background: -ms-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 33 | background: -o-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 34 | background: linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 35 | color: #464646; 36 | } 37 | 38 | .wrapper { 39 | max-width: 1200px; 40 | min-width: 1000px; 41 | margin: 0 auto; 42 | } 43 | main { 44 | overflow: hidden; 45 | } 46 | header { 47 | position: relative; 48 | overflow: hidden; 49 | } 50 | nav { 51 | position: absolute; 52 | top: 0; 53 | bottom: 0; 54 | right: 0; 55 | margin: 0; 56 | height: 50px; 57 | line-height: 50px; 58 | margin-top: auto; 59 | margin-bottom: auto; 60 | } 61 | nav ul { 62 | margin: 0; 63 | } 64 | nav ul li { 65 | display: inline-block; 66 | vertical-align: middle; 67 | } 68 | nav ul li + li { 69 | margin-left: 20px; 70 | } 71 | nav ul li a { 72 | display: block; 73 | } 74 | nav img { 75 | margin-right: 10px; 76 | } 77 | 78 | ol li + li { 79 | margin-top: 10px; 80 | } 81 | hr { 82 | border-style: solid; 83 | border-color: #000; 84 | border-width: 1px 0 0 0; 85 | } 86 | 87 | h1 img { 88 | position: relative; 89 | top: -4px; 90 | margin-right: 10px; 91 | } 92 | 93 | .content-capture { 94 | float: right; 95 | width: 60%; 96 | margin-top: 20px; 97 | /* margin-left: 30px; */ 98 | -webkit-box-reflect: below 40px 99 | -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.3) 0%, transparent 50%, transparent 100%); 100 | } 101 | .content-body { 102 | float: left; 103 | width: 40%; 104 | padding-right: 30px; 105 | box-sizing: border-box; 106 | } 107 | 108 | h3 + * { 109 | position: relative; 110 | } 111 | .browser-support { 112 | position: absolute; 113 | top: 10px; 114 | right: 15px; 115 | } 116 | .browser-support > li.disabled { 117 | -webkit-filter: grayscale(1); 118 | -webkit-filter: grayscale(100%); 119 | filter: grayscale(100%); 120 | filter: gray; 121 | filter: url("data:image/svg+xml;utf8,#greyscale"); 122 | } 123 | 124 | .browser-support > li { 125 | float: right; 126 | } 127 | .browser-support > li + li { 128 | margin-right: 5px; 129 | } 130 | .browser-support > li img { 131 | width: 20px; 132 | height: auto; 133 | } 134 | h3 + * a { 135 | display: block; 136 | padding: 10px 15px; 137 | /*border: 1px solid #E9E9E9;*/ 138 | border: 1px solid transparent; 139 | text-decoration: none !important; 140 | -webkit-transition: 0.2s ease; 141 | -moz-transition: 0.2s ease; 142 | -ms-transition: 0.2s ease; 143 | -o-transition: 0.2s ease; 144 | transition: 0.2s ease; 145 | background-color: rgba(255, 255, 255, 0.7); 146 | color: #359C62 !important; 147 | } 148 | h3 + * a:hover { 149 | /*background-color: white;*/ 150 | border-color: rgb(49, 194, 92); 151 | } 152 | h3 + * a > img { 153 | margin-top: 10px; 154 | } 155 | 156 | #bookmarklet:after { 157 | content: 'Bookmark this link.'; 158 | display: block; 159 | color: #7C7D80 !important; 160 | } -------------------------------------------------------------------------------- /src/page/demo1.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | /* reset */ 4 | ul { 5 | list-style: none; 6 | } 7 | 8 | img { 9 | vertical-align: middle; 10 | } 11 | 12 | /* anchors */ 13 | a:link, 14 | a:visited { 15 | color: #359C62; 16 | text-decoration: none; 17 | } 18 | a:hover, 19 | a:active { 20 | text-decoration: underline; 21 | } 22 | 23 | html { 24 | font-family: Roboto, 'Noto', 'Helvetica Neue', Helvetica, Arial, sans-serif; 25 | } 26 | 27 | /* page style */ 28 | body { 29 | padding: 2vw 4vw; 30 | background: -webkit-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 31 | background: -moz-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 32 | background: -ms-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 33 | background: -o-linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 34 | background: linear-gradient(90deg, #F1F8FF 10%, rgba(7, 234, 215, 0.11) 90%); 35 | color: #464646; 36 | } 37 | 38 | .wrapper { 39 | max-width: 1200px; 40 | min-width: 1000px; 41 | margin: 0 auto; 42 | } 43 | main { 44 | overflow: hidden; 45 | } 46 | header { 47 | position: relative; 48 | overflow: hidden; 49 | } 50 | nav { 51 | position: absolute; 52 | top: 0; 53 | bottom: 0; 54 | right: 0; 55 | margin: 0; 56 | height: 50px; 57 | line-height: 50px; 58 | margin-top: auto; 59 | margin-bottom: auto; 60 | } 61 | nav ul { 62 | margin: 0; 63 | } 64 | nav ul li { 65 | display: inline-block; 66 | vertical-align: middle; 67 | } 68 | nav ul li + li { 69 | margin-left: 20px; 70 | } 71 | nav ul li a { 72 | display: block; 73 | } 74 | nav img { 75 | margin-right: 10px; 76 | } 77 | 78 | ol li + li { 79 | margin-top: 10px; 80 | } 81 | hr { 82 | border-style: solid; 83 | border-color: #000; 84 | border-width: 1px 0 0 0; 85 | } 86 | 87 | h1 img { 88 | position: relative; 89 | top: -4px; 90 | margin-right: 10px; 91 | } 92 | 93 | .content-capture { 94 | float: right; 95 | width: 60%; 96 | margin-top: 20px; 97 | /* margin-left: 30px; */ 98 | -webkit-box-reflect: below 40px 99 | -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.3) 0%, transparent 50%, transparent 100%); 100 | } 101 | .content-body { 102 | float: left; 103 | width: 40%; 104 | padding-right: 30px; 105 | box-sizing: border-box; 106 | } 107 | 108 | h3 + * { 109 | position: relative; 110 | } 111 | .browser-support { 112 | position: absolute; 113 | top: 10px; 114 | right: 15px; 115 | } 116 | .browser-support > li.disabled { 117 | -webkit-filter: grayscale(1); 118 | -webkit-filter: grayscale(100%); 119 | filter: grayscale(100%); 120 | filter: gray; 121 | filter: url("data:image/svg+xml;utf8,#greyscale"); 122 | } 123 | 124 | .browser-support > li { 125 | float: right; 126 | } 127 | .browser-support > li + li { 128 | margin-right: 5px; 129 | } 130 | .browser-support > li img { 131 | width: 20px; 132 | height: auto; 133 | } 134 | h3 + * a { 135 | display: block; 136 | padding: 10px 15px; 137 | /*border: 1px solid #E9E9E9;*/ 138 | border: 1px solid transparent; 139 | text-decoration: none !important; 140 | -webkit-transition: 0.2s ease; 141 | -moz-transition: 0.2s ease; 142 | -ms-transition: 0.2s ease; 143 | -o-transition: 0.2s ease; 144 | transition: 0.2s ease; 145 | background-color: rgba(255, 255, 255, 0.7); 146 | color: #359C62 !important; 147 | } 148 | h3 + * a:hover { 149 | /*background-color: white;*/ 150 | border-color: rgb(49, 194, 92); 151 | } 152 | h3 + * a > img { 153 | margin-top: 10px; 154 | } 155 | 156 | #bookmarklet:after { 157 | content: 'Bookmark this link.'; 158 | display: block; 159 | color: #7C7D80 !important; 160 | } -------------------------------------------------------------------------------- /src/page/demo2.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | html { 3 | /*line-height: 1.7;*/ 4 | } 5 | html body span:nth-child(1) { 6 | width: 6000px; 7 | } 8 | body span:nth-child(1) { 9 | width: 400px; 10 | } 11 | span:nth-child(1) { 12 | width: 9000px !important; 13 | } 14 | 15 | span:nth-child(2) { 16 | width: 300px !important; 17 | } 18 | span:nth-child(2) { 19 | width: 300px !important; 20 | } 21 | span:nth-child(3) { 22 | width: 200px !important; 23 | } 24 | span:nth-child(4) { 25 | width: 100px !important; 26 | } 27 | 28 | div.a { 29 | width: auto; 30 | } 31 | div.b { 32 | width: 100%; 33 | } 34 | div.c { 35 | width: 5em; 36 | } 37 | input { 38 | width: 300px; 39 | } 40 | 41 | p { 42 | width: 30px; 43 | margin-left: auto; 44 | /*line-height: 2;*/ 45 | } 46 | span { 47 | line-height: 3; 48 | } -------------------------------------------------------------------------------- /src/page/demo2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Demo | Style Validator 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 75 | 76 | 77 | 78 | span with style of CSS Rule with no-important(non-replaced inline element) 79 | span with style of CSS Rule with important(non-replaced inline element) 80 | span with style of style attribute with important(non-replaced inline element) 81 | span with style of style attribute with no-important(non-replaced inline element) 82 | span with style of style attribute with no-important(non-replaced inline element) 83 | 84 |

    p css rule

    85 |

    p style attribute

    86 | 87 |
    div
    88 |
    div
    89 |
    div
    90 |
    div
    91 |
    div
    92 | img(replaced inline empty element) 93 | 94 | canvas 95 | 96 |
    97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/page/demo3.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | div:after { 4 | content: ''; 5 | /*clear: both;*/ 6 | } 7 | p { 8 | float: left; 9 | display: inline; 10 | } 11 | 12 | img::after { 13 | content: 'a'; 14 | } -------------------------------------------------------------------------------- /src/page/demo3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
    7 |

    float element

    8 | 9 |
    10 | 11 | -------------------------------------------------------------------------------- /src/page/demo4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
    5 |

    no parent flex element

    6 |
    7 | 8 | -------------------------------------------------------------------------------- /src/page/index.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | .main { 4 | /*opacity: 0;*/ 5 | /*transition: opacity 1.5s ease;*/ 6 | } 7 | .main.fadeIn { 8 | /*opacity: 1;*/ 9 | } 10 | 11 | .installation { 12 | background: #8FFFCB; 13 | padding: 7% 2%; 14 | } 15 | .installation-heading { 16 | font-size: 35px; 17 | text-align: center; 18 | margin-bottom: 5%; 19 | } 20 | .buttons { 21 | display: flex; 22 | justify-content: center; 23 | } 24 | 25 | .kv { 26 | display: flex; 27 | justify-content: center; 28 | max-width: 1000px; 29 | margin-right: auto; 30 | margin-left: auto; 31 | padding-top: 4%; 32 | padding-bottom: 8%; 33 | } 34 | .kv-logo { 35 | /* margin-right: 2%; */ 36 | flex-basis: 33.3%; 37 | margin-top: auto; 38 | margin-bottom: auto; 39 | } 40 | .kv-logo > * { 41 | /* -webkit-box-reflect: below 30px 42 | -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.3) 0%, transparent 30%, transparent 100%); */ 43 | } 44 | .kv-caption { 45 | margin-top: auto; 46 | margin-bottom: auto; 47 | padding-left: 5%; 48 | flex-basis: 66.6%; 49 | } 50 | .kv-header { 51 | display: flex; 52 | margin-bottom: 5%; 53 | } 54 | .kv-heading { 55 | font-size: calc(1vw + 28px); 56 | font-weight: normal; 57 | color: #45853C; 58 | background: -webkit-linear-gradient(left, #355431 0%,#45853C 100%); 59 | -webkit-background-clip: text; 60 | -webkit-text-fill-color: transparent; 61 | line-height: 1.1; 62 | } 63 | .kv-heading span { 64 | white-space: nowrap; 65 | } 66 | .kv-body { 67 | font-size: 15px; 68 | } 69 | 70 | .note-list > li + li { 71 | margin-top: 10px; 72 | } 73 | hr { 74 | border-style: solid; 75 | border-color: #000; 76 | border-width: 1px 0 0 0; 77 | } 78 | .main-body { 79 | padding-right: 30px; 80 | box-sizing: border-box; 81 | } 82 | .section { 83 | } 84 | .section-header { 85 | text-align: center; 86 | /*margin-bottom: 2%;*/ 87 | } 88 | .section-header + * { 89 | margin-top: 4%; 90 | } 91 | .section-heading { 92 | font-size: calc(2vw + 16px); 93 | font-weight: normal; 94 | } 95 | .section-description { 96 | font-size: calc(1vw + 2px); 97 | } 98 | .section-body { 99 | text-align: center; 100 | } 101 | 102 | .section-slideshare { 103 | color: white; 104 | background: darkslateblue; 105 | } 106 | 107 | .section-validate { 108 | margin-top: 6%; 109 | padding: 6px 12px; 110 | border: 1px solid transparent; 111 | text-decoration: none !important; 112 | transition: 0.2s ease; 113 | background-color: white; 114 | color: #359C62 !important; 115 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); 116 | } 117 | .section-validate-header { 118 | display: flex; 119 | justify-content: space-between; 120 | flex-flow: row wrap; 121 | } 122 | .section-validate-heading { 123 | font-weight: normal; 124 | text-align: left; 125 | } 126 | .section-validate-header + .section-validate-body { 127 | margin-top: 5px; 128 | } 129 | .section-validate-form { 130 | display: flex; 131 | } 132 | .section-validate-input[type] { 133 | flex: 1 1 auto; 134 | font-size: calc(10px + 0.8vw); 135 | padding: 10px; 136 | border: 0; 137 | width: 1em; 138 | outline: 0; 139 | border-bottom: 1px solid #289C1F; 140 | } 141 | .section-validate-button { 142 | font-size: 13px; 143 | padding-right: 10px; 144 | padding-left: 10px; 145 | margin-left: 10px; 146 | } 147 | 148 | .section-video { 149 | position: relative; 150 | background-color: #C3F5E7; 151 | } 152 | .section-video .section-body { 153 | overflow: hidden; 154 | /*margin-top: -10%;*/ 155 | border-radius: 3px; 156 | /*box-shadow: 0 0 16px 0 rgba(0, 0, 0, 0.1);*/ 157 | } 158 | .section-video-tag { 159 | margin-top: -1.8%; 160 | margin-bottom: -0.8%; 161 | max-width: 100%; 162 | height: auto; 163 | } 164 | .section-gif-animation { 165 | max-width: 100%; 166 | height: auto; 167 | } 168 | .section-feature { 169 | background: #FFFF8E; 170 | } 171 | .section-feature * { 172 | background: inherit; 173 | } 174 | .section-feature-descriptions { 175 | position: relative; 176 | z-index: 100; 177 | font-size: calc(1vw + 10px); 178 | margin: 6%; 179 | line-height: 1.2; 180 | } 181 | .section-feature-descriptions > * + * { 182 | margin-top: 2%; 183 | } 184 | .section-feature-list { 185 | position: relative; 186 | display: flex; 187 | padding-bottom: 48%; 188 | } 189 | .section-feature-list:before, 190 | .section-feature-list:after { 191 | content: ''; 192 | position: absolute; 193 | top: 0; 194 | left: 0; 195 | right: 0; 196 | width: 70%; 197 | height: 0; 198 | margin-right: auto; 199 | margin-left: auto; 200 | margin-top: -20%; 201 | padding-bottom: 60%; 202 | } 203 | .section-feature-list:before { 204 | border: 1px solid #DCDCD7; 205 | border-radius: 50% 50%; 206 | } 207 | 208 | .section-feature-list:after { 209 | content: ''; 210 | background: url(/img/style-validator.logo.svg) no-repeat center center; 211 | background-size: 20% auto; 212 | } 213 | .section-feature-list > li { 214 | position: absolute; 215 | width: 33.333%; 216 | background: inherit; 217 | text-align: center; 218 | } 219 | .section-feature-list > li img { 220 | width: 80%; 221 | max-width: 160px; 222 | height: auto; 223 | border: 5px solid #FFFF8E; 224 | } 225 | .section-feature-html { 226 | left: 0; 227 | } 228 | .section-feature-css { 229 | bottom: 0; 230 | left: 33.333%; 231 | } 232 | .section-feature-js { 233 | left: 66.666%; 234 | } 235 | .section-feature-js img { 236 | width: 70% !important; 237 | } 238 | .section-rules { 239 | background: white; 240 | } 241 | .section-video img, 242 | .section-rules img { 243 | box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.2); 244 | } 245 | .section-rules-steps { 246 | counter-reset: section-rules-index; 247 | } 248 | .section-rules-steps > dt { 249 | font-size: 1.5rem; 250 | } 251 | .section-rules-steps > dt:before { 252 | counter-increment: section-rules-index; 253 | content: counter(section-rules-index) '.'; 254 | margin-right: 0.5em; 255 | } 256 | .section-rules-steps > dt + dd { 257 | margin-top: 2%; 258 | } 259 | .section-rules-steps > dd + dt { 260 | margin-top: 4%; 261 | } 262 | .section-loadmap .section-body { 263 | text-align: left; 264 | font-size: 1.2rem; 265 | } 266 | .section-loadmap ol > li + li { 267 | margin-top: 1rem; 268 | } 269 | 270 | @media (max-width: 640px) { 271 | 272 | .kv { 273 | flex-direction: column; 274 | } 275 | .kv > * { 276 | flex-basis: auto; 277 | } 278 | .kv-logo { 279 | height: 200px; 280 | padding: 20px 5% 60px; 281 | position: absolute; 282 | opacity: 0.1; 283 | right: 0; 284 | left: 0; 285 | top: 20%; 286 | } 287 | .kv-caption { 288 | padding-left: 0; 289 | text-align: center; 290 | position: relative; 291 | } 292 | .kv-header { 293 | justify-content: center; 294 | } 295 | } -------------------------------------------------------------------------------- /src/page/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var STYLEV = STYLEV || {}; 4 | 5 | STYLEV.TOPPAGE = STYLEV.TOPPAGE || {}; 6 | 7 | STYLEV.TOPPAGE.FIRST_ANIMATION = { 8 | 9 | execute: function() { 10 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 11 | that.setParameter(); 12 | that.bindEvents(); 13 | // that.startAnimation(); 14 | that.animateSVG(); 15 | that.getBookmarklet(); 16 | document.removeEventListener('WebComponentsReady', STYLEV.TOPPAGE.FIRST_ANIMATION.execute); 17 | //document.querySelector('input[type="text"]').focus(); 18 | }, 19 | 20 | setParameter: function() { 21 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 22 | 23 | that.html = document.documentElement; 24 | that.wrapper = document.querySelector('.wrapper'); 25 | that.main = document.querySelector('.main'); 26 | that.header = document.querySelector('.header'); 27 | that.submitForm = document.querySelector('#validation-form'); 28 | that.submitInput = document.querySelector('#validation-input'); 29 | that.submitButton = document.querySelector('#validation-button'); 30 | }, 31 | 32 | bindEvents: function() { 33 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 34 | 35 | // window.addEventListener('resize', that.adjustWrapperPosition); 36 | window.addEventListener('scroll', that.fixHeaderOnScroll); 37 | that.submitForm.addEventListener('submit', that.submitValidation); 38 | }, 39 | 40 | submitValidation: function(event) { 41 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 42 | event.preventDefault(); 43 | 44 | var data = { 45 | url: that.submitInput.value 46 | }; 47 | 48 | that.submit(data); 49 | }, 50 | 51 | submit: function(data) { 52 | var targetURL; 53 | if(data.url.indexOf('http') === 0) { 54 | targetURL = data.url; 55 | } else { 56 | targetURL = 'http://' + data.url; 57 | } 58 | 59 | var apiURI = '/page/result.html?url=' + targetURL; 60 | location.href = apiURI; 61 | }, 62 | 63 | throwError: function(error) { 64 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 65 | throw new Error(error || 'Connection failed.'); 66 | }, 67 | 68 | startAnimation: function() { 69 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 70 | 71 | //setTimeout(that.startFadeIn, 100); 72 | // setTimeout(that.adjustWrapperPosition, 0); 73 | }, 74 | 75 | adjustWrapperPosition: function() { 76 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 77 | 78 | if(that.adjustWrapperPositionTimer !== undefined) { 79 | clearTimeout(that.adjustWrapperPositionTimer); 80 | } 81 | that.adjustWrapperPositionTimer = setTimeout(function() { 82 | that.wrapper.style.setProperty('padding-top', that.header.offsetHeight + 'px', ''); 83 | }, 0); 84 | }, 85 | 86 | fixHeaderOnScroll: function() { 87 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 88 | var isNotDefaultPosY = window.scrollY > 0; 89 | if(isNotDefaultPosY) { 90 | that.html.classList.add('is-fixed-header'); 91 | } else { 92 | that.html.classList.remove('is-fixed-header'); 93 | } 94 | }, 95 | 96 | startFadeIn: function () { 97 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 98 | 99 | that.main.classList.add('fadeIn'); 100 | }, 101 | 102 | animateSVG: function() { 103 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 104 | 105 | 106 | 107 | new Vivus('vivus-kv-logo', { 108 | duration: 200, 109 | file: '/img/style-validator.logo.nopadding.svg', 110 | type: 'async' 111 | }); 112 | }, 113 | 114 | getBookmarklet: function() { 115 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 116 | $.ajax({ 117 | url: $('#bookmarklet').attr('href'), 118 | dataType: 'text', 119 | success: that.setBookmarklet 120 | }); 121 | }, 122 | 123 | setBookmarklet: function(data) { 124 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 125 | $('#bookmarklet').attr('href', data); 126 | } 127 | 128 | }; 129 | 130 | document.addEventListener('WebComponentsReady', STYLEV.TOPPAGE.FIRST_ANIMATION.execute); 131 | -------------------------------------------------------------------------------- /src/page/references.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | -------------------------------------------------------------------------------- /src/page/references.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | References | Style Validator 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 75 | 76 |
    77 |
    78 |

    References

    79 |
    80 |
    81 | Why Page 82 | 85 | 86 |
    87 |
    88 | 89 | 90 | -------------------------------------------------------------------------------- /src/page/result.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | .result-wrapper { 4 | flex: 1 0 auto; 5 | display: flex; 6 | flex-flow: column nowrap; 7 | padding-bottom: 5%; 8 | } 9 | 10 | .result { 11 | display: flex; 12 | flex-wrap: wrap; 13 | /*padding-bottom: 5%;*/ 14 | } 15 | .result-screenshot { 16 | position: relative; 17 | flex: 1 0 70%; 18 | padding: 30% 0; 19 | background: url(/img/macbook-pro-retina.png) no-repeat center center; 20 | background-size: 116% auto; 21 | text-align: center; 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | .result-screenshot-display { 27 | position: absolute; 28 | top: 15%; 29 | right: 15%; 30 | bottom: 15%; 31 | /* left: 0; */ 32 | width: 70%; 33 | height: auto; 34 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); 35 | margin-top: -3.5%; 36 | overflow-x: hidden; 37 | overflow-y: auto; 38 | } 39 | .screenshot-image { 40 | width: 100%; 41 | height: auto; 42 | } 43 | .result-body { 44 | display: none !important;/*TODO: refactor!*/ 45 | padding: 4%; 46 | flex: 1 0 auto; 47 | } 48 | .result-table { 49 | font-size: 18px; 50 | } 51 | .result-table th { 52 | text-align: left; 53 | } 54 | .result-table th, 55 | .result-table td { 56 | padding: 5px 10px; 57 | } 58 | 59 | .result-table td { 60 | font-size: 26px; 61 | } 62 | * + .result-kv-buttons { 63 | margin-top: 5%; 64 | } 65 | .result-kv-buttons { 66 | padding: 1.5rem 1rem 1.5rem; 67 | margin-right: auto; 68 | margin-left: auto; 69 | max-width: 50rem; 70 | border-top: 1px solid #768a7e; 71 | } 72 | .result-kv-buttons-header { 73 | 74 | } 75 | .result-kv-buttons-heading { 76 | font-size: calc(1rem + 1vw); 77 | } -------------------------------------------------------------------------------- /src/page/result.hbs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
    Total: {{total}}
    Error: {{error}}
    Warning: {{warning}}
    14 |
    15 |
    16 |
    17 | Screenshot 18 |
    19 |
    20 |
    -------------------------------------------------------------------------------- /src/page/result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Validation Result - Style Validator - A Next CSS Validator 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 76 | 77 | 78 |
    79 | 80 |
    81 |
    82 | 83 |
    84 |
    85 |

    This result page is under development, so try the Apps for production!

    86 |
    87 | 124 |
    125 |
    126 | 127 |
    128 |
    129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /src/page/result.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var STYLEV = STYLEV || {}; 4 | 5 | STYLEV.TOPPAGE = STYLEV.TOPPAGE || {}; 6 | 7 | STYLEV.TOPPAGE.FIRST_ANIMATION = { 8 | 9 | execute: function() { 10 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 11 | that.setParameter(); 12 | that.bindEvents(); 13 | // that.startAnimation(); 14 | that.getBookmarklet(); 15 | 16 | //document.querySelector('input[type="text"]').focus(); 17 | }, 18 | 19 | setParameter: function() { 20 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 21 | 22 | that.html = document.documentElement; 23 | that.wrapper = document.querySelector('.wrapper'); 24 | that.main = document.querySelector('.main'); 25 | that.header = document.querySelector('.header'); 26 | }, 27 | 28 | bindEvents: function() { 29 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 30 | 31 | // window.addEventListener('resize', that.adjustWrapperPosition); 32 | // window.addEventListener('scroll', that.fixHeaderOnScroll); 33 | }, 34 | 35 | startAnimation: function() { 36 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 37 | 38 | setTimeout(that.adjustWrapperPosition, 0); 39 | }, 40 | 41 | adjustWrapperPosition: function() { 42 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 43 | 44 | if(that.adjustWrapperPositionTimer !== undefined) { 45 | clearTimeout(that.adjustWrapperPositionTimer); 46 | } 47 | that.adjustWrapperPositionTimer = setTimeout(function() { 48 | that.wrapper.style.setProperty('padding-top', that.header.offsetHeight + 'px', ''); 49 | }, 0); 50 | }, 51 | 52 | fixHeaderOnScroll: function() { 53 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 54 | var isNotDefaultPosY = window.scrollY > 0; 55 | if(isNotDefaultPosY) { 56 | that.html.classList.add('is-fixed-header'); 57 | } else { 58 | that.html.classList.remove('is-fixed-header'); 59 | } 60 | }, 61 | 62 | getBookmarklet: function() { 63 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 64 | $.ajax({ 65 | url: $('#bookmarklet').attr('href'), 66 | dataType: 'text', 67 | success: that.setBookmarklet 68 | }); 69 | }, 70 | 71 | setBookmarklet: function(data) { 72 | var that = STYLEV.TOPPAGE.FIRST_ANIMATION; 73 | $('#bookmarklet').attr('href', data); 74 | } 75 | }; 76 | 77 | document.addEventListener('WebComponentsReady', STYLEV.TOPPAGE.FIRST_ANIMATION.execute); 78 | -------------------------------------------------------------------------------- /src/webdriverio.test.js: -------------------------------------------------------------------------------- 1 | var webdriverio = require('webdriverio'); 2 | var options = { desiredCapabilities: { 3 | browserName: 'chrome', 4 | chromeOptions: { 5 | 'binary': '/usr/bin/google-chrome' 6 | } 7 | 8 | } }; 9 | var client = webdriverio.remote(options); 10 | 11 | client 12 | .init() 13 | .url('https://www.google.com/') 14 | .getTitle() 15 | .then(function(title) { 16 | console.log('Title is: ' + title); 17 | // outputs: "Title is: WebdriverIO (Software) at DuckDuckGo" 18 | }) 19 | .end(); -------------------------------------------------------------------------------- /videos/style-validator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/videos/style-validator.jpg -------------------------------------------------------------------------------- /videos/style-validator.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/videos/style-validator.m4v -------------------------------------------------------------------------------- /videos/style-validator.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Style-Validator/style-validator/236ea0458262f07b106ed8562967099ef40ce41b/videos/style-validator.webm -------------------------------------------------------------------------------- /why.md: -------------------------------------------------------------------------------- 1 | Why we need to detect `Risky Style`? 2 | ============================ 3 | 4 | # Too complicated CSS 5 | 6 | - Over 300 CSS properties (if include pattern of value... it's insane volume) 7 | - Over 10,000 Browser types (including mobile) 8 | - Other Front-end technology has evolved too much (We are so hard to develop...) 9 | 10 | The Risky Style will cause**Unintended Behavior**in the browser such as layout breaking. 11 | 12 | But we have no way to detect it. So,**Cross Browser CSS is too difficult**. 13 | 14 | 15 | ## Problems of Current CSS Validator 16 | 17 | - Can not validate CSS after JavaScript and Media Queries 18 | - Can not validate Computed Style (It can validate only syntax) 19 | - Can not validate Adaptability of between CSS properties and HTML tags 20 | 21 | 22 | ## Risky CSS Property cause... 23 | 24 | - Really Many Bugs&Meaningless Patches :( 25 | - Interrupting creative ideas :( 26 | - Loss of valuable engineer’s life :( 27 | 28 | Style Validator is solution that resolves these problems. 29 | 30 | --------------------------------------------------------------------------------