├── src ├── fonts │ ├── ls-icons.eot │ ├── ls-icons.ttf │ ├── ls-icons.woff │ └── ls-icons.svg ├── img │ ├── F7F7F7-0.9.png │ └── licenses │ │ ├── bsd.png │ │ ├── by.png │ │ ├── cc.png │ │ ├── gpl.png │ │ ├── mit.png │ │ ├── nc.png │ │ ├── nd.png │ │ ├── osi.png │ │ ├── pd.png │ │ ├── sa.png │ │ ├── agpl3.png │ │ ├── apache.png │ │ ├── gpl3.png │ │ ├── lgpl.png │ │ ├── lgpl3.png │ │ ├── perl.png │ │ ├── zero.png │ │ ├── copyleft.png │ │ ├── eclipse.png │ │ ├── mozilla.png │ │ ├── opendata.png │ │ ├── copyright.png │ │ ├── copyright.svg │ │ ├── osi.svg │ │ ├── by.svg │ │ ├── sa.svg │ │ ├── pd.svg │ │ ├── nc.svg │ │ ├── copyleft.svg │ │ ├── zero.svg │ │ ├── gpl.svg │ │ ├── cc.svg │ │ ├── lgpl.svg │ │ ├── perl.svg │ │ ├── mit.svg │ │ ├── nd.svg │ │ ├── gpl3.svg │ │ ├── lgpl3.svg │ │ ├── agpl3.svg │ │ ├── eclipse.svg │ │ └── mozilla.svg ├── index.coffee ├── core │ ├── search.coffee │ ├── modal.coffee │ ├── question.coffee │ ├── tooltip.coffee │ ├── license-selector.coffee │ ├── history.coffee │ └── license-list.coffee ├── plugins │ └── jquery.coffee ├── data │ ├── labels.coffee │ ├── compatibility.coffee │ └── questions.coffee ├── tooltip.less ├── mixins.less ├── helpers │ └── explanations.coffee ├── modal.less ├── license-selector.less └── variables.less ├── babel.config.json ├── .mversionrc ├── .gitignore ├── .npmignore ├── Makefile ├── .editorconfig ├── Acknowledgment-ReadMe.md ├── cypress.config.js ├── cypress ├── support │ ├── e2e.js │ └── commands.js └── e2e │ └── license-selector.cy.js ├── bower.json ├── index.d.ts ├── LICENSE.md ├── webpack.config-old.js ├── webpack.config.js ├── index.html ├── package.json ├── docs └── extending.md └── .github └── workflows └── deploy.yml /src/fonts/ls-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/fonts/ls-icons.eot -------------------------------------------------------------------------------- /src/fonts/ls-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/fonts/ls-icons.ttf -------------------------------------------------------------------------------- /src/img/F7F7F7-0.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/F7F7F7-0.9.png -------------------------------------------------------------------------------- /src/fonts/ls-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/fonts/ls-icons.woff -------------------------------------------------------------------------------- /src/img/licenses/bsd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/bsd.png -------------------------------------------------------------------------------- /src/img/licenses/by.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/by.png -------------------------------------------------------------------------------- /src/img/licenses/cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/cc.png -------------------------------------------------------------------------------- /src/img/licenses/gpl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/gpl.png -------------------------------------------------------------------------------- /src/img/licenses/mit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/mit.png -------------------------------------------------------------------------------- /src/img/licenses/nc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/nc.png -------------------------------------------------------------------------------- /src/img/licenses/nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/nd.png -------------------------------------------------------------------------------- /src/img/licenses/osi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/osi.png -------------------------------------------------------------------------------- /src/img/licenses/pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/pd.png -------------------------------------------------------------------------------- /src/img/licenses/sa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/sa.png -------------------------------------------------------------------------------- /src/img/licenses/agpl3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/agpl3.png -------------------------------------------------------------------------------- /src/img/licenses/apache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/apache.png -------------------------------------------------------------------------------- /src/img/licenses/gpl3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/gpl3.png -------------------------------------------------------------------------------- /src/img/licenses/lgpl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/lgpl.png -------------------------------------------------------------------------------- /src/img/licenses/lgpl3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/lgpl3.png -------------------------------------------------------------------------------- /src/img/licenses/perl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/perl.png -------------------------------------------------------------------------------- /src/img/licenses/zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/zero.png -------------------------------------------------------------------------------- /src/img/licenses/copyleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/copyleft.png -------------------------------------------------------------------------------- /src/img/licenses/eclipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/eclipse.png -------------------------------------------------------------------------------- /src/img/licenses/mozilla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/mozilla.png -------------------------------------------------------------------------------- /src/img/licenses/opendata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/opendata.png -------------------------------------------------------------------------------- /src/img/licenses/copyright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufal/public-license-selector/HEAD/src/img/licenses/copyright.png -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "browsers": [">0.2%", "not dead", "not op_mini all"] 8 | } 9 | } 10 | ] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.mversionrc: -------------------------------------------------------------------------------- 1 | { 2 | "commitMessage": "Releasing %s", 3 | "tagName": "v%s", 4 | "scripts": { 5 | "preupdate": "echo 'Releasing new version...'", 6 | "postcommit": "git push origin master --follow-tags", 7 | "postupdate": "echo 'Updated to version %s'" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directory 2 | # Commenting this out is preferred by some people, see 3 | # https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 4 | node_modules 5 | 6 | # No bower components 7 | bower_components 8 | 9 | # Ignore build directories 10 | dist 11 | 12 | # Users Environment Variables 13 | .lock-wscript 14 | .idea 15 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Development files 2 | src/ 3 | ci/ 4 | docs/ 5 | .github/ 6 | node_modules/ 7 | 8 | # Build configs 9 | webpack.config.js 10 | webpack.config-old.js 11 | babel.config.json 12 | .mversionrc 13 | .editorconfig 14 | Makefile 15 | 16 | # CI/CD 17 | .travis.yml 18 | 19 | # Documentation (already in README) 20 | testing-plan.md 21 | 22 | # Demo files 23 | index.html 24 | 25 | # Obsolete 26 | bower.json 27 | 28 | # Source maps (optional - remove if you want to include them) 29 | *.map 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | 3 | build: 4 | @npm run build 5 | 6 | install: 7 | @npm install 8 | 9 | run: 10 | @echo "**************************************************" 11 | @echo "* open http://localhost:8080/webpack-dev-server/ *" 12 | @echo "**************************************************" 13 | @npm start 14 | 15 | release: 16 | @./node_modules/.bin/mversion patch 17 | 18 | release-minor: 19 | @./node_modules/.bin/mversion minor 20 | 21 | release-major: 22 | @./node_modules/.bin/mversion major 23 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | 23 | # Tab indentation (no size specified) 24 | [Makefile] 25 | indent_style = tab 26 | -------------------------------------------------------------------------------- /src/index.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Module: index.coffee 3 | # Summary: Entry point that re-exports the selector and bundled data helpers. 4 | ### 5 | LicenseSelector = require './core/license-selector' 6 | LicenseDefinitions = require './data/licenses' 7 | LicenseCompatibility = require './data/compatibility' 8 | QuestionDefinitions = require './data/questions' 9 | LabelsDefinitions = require './data/labels' 10 | 11 | require './plugins/jquery' 12 | 13 | module.exports = 14 | LicenseSelector: LicenseSelector 15 | LicenseDefinitions: LicenseDefinitions 16 | LicenseCompatibility: LicenseCompatibility 17 | QuestionDefinitions: QuestionDefinitions 18 | LabelsDefinitions: LabelsDefinitions 19 | -------------------------------------------------------------------------------- /Acknowledgment-ReadMe.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
12 |
13 |
If you see this without closing the License Selector please reload the page.
27 | 28 | 29 | 30 | 31 | 32 | 33 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/img/licenses/perl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/img/licenses/mit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 98 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ufal/license-selector", 3 | "title": "License Selector", 4 | "version": "0.1.4", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/ufal/public-license-selector.git" 8 | }, 9 | "description": "JQuery plugin with UI for picking a license for software or data", 10 | "main": "dist/license-selector.umd.js", 11 | "module": "dist/license-selector.esm.js", 12 | "types": "index.d.ts", 13 | "files": [ 14 | "dist/", 15 | "index.d.ts", 16 | "LICENSE.md", 17 | "README.md" 18 | ], 19 | "homepage": "http://ufal.github.io/public-license-selector", 20 | "keywords": [ 21 | "license", 22 | "selector", 23 | "license selector", 24 | "public license", 25 | "software license", 26 | "data license", 27 | "jquery plugin" 28 | ], 29 | "devDependencies": { 30 | "@babel/core": "^7.23.0", 31 | "@babel/preset-env": "^7.23.0", 32 | "babel-loader": "^9.1.3", 33 | "coffee-loader": "^3.0.0", 34 | "coffee-script": "^1.12.7", 35 | "cross-env": "^7.0.3", 36 | "css-loader": "^6.8.1", 37 | "cypress": "^13.6.0", 38 | "html-webpack-plugin": "^5.5.3", 39 | "less": "^4.2.0", 40 | "less-loader": "^11.1.3", 41 | "lodash": "^4.17.21", 42 | "mini-css-extract-plugin": "^2.7.6", 43 | "npm-run-all": "^4.1.5", 44 | "rimraf": "^5.0.5", 45 | "webpack": "^5.88.2", 46 | "webpack-cli": "^5.1.4", 47 | "webpack-dev-server": "^4.15.1" 48 | }, 49 | "peerDependencies": { 50 | "jquery": ">=2.1.1", 51 | "lodash": ">=2.4.1" 52 | }, 53 | "scripts": { 54 | "clean": "rimraf dist", 55 | "build:umd": "cross-env NODE_ENV=production webpack --config webpack.config.js --env bundle=umd", 56 | "build:esm": "cross-env NODE_ENV=production webpack --config webpack.config.js --env bundle=esm", 57 | "build": "npm-run-all clean build:umd build:esm", 58 | "prepublishOnly": "npm run build", 59 | "start": "cross-env NODE_ENV=development webpack serve --config webpack.config.js --env bundle=umd --open", 60 | "test": "npm-run-all build test:e2e", 61 | "test:e2e": "cypress run", 62 | "test:open": "cypress open", 63 | "test:headed": "cypress run --headed --browser chrome", 64 | "test:ci": "cypress run --browser chrome", 65 | "generate-graph": "node scripts/generate-state-graph.js" 66 | }, 67 | "engines": { 68 | "node": ">=0.8.0" 69 | }, 70 | "author": { 71 | "name": "ÚFAL", 72 | "email": "ufal@ufal.mff.cuni.cz", 73 | "url": "https://ufal.mff.cuni.cz/" 74 | }, 75 | "authors": [ 76 | "Pawel Kamocki", 77 | "Pavel Straňák", 78 | "Michal Sedlák" 79 | ], 80 | "maintainers": [ 81 | "Ondřej Košarko14 | Copyright protects original works. Originality is defined as the author’s own 15 | intellectual creation. Therefore, mere statements of historical facts, results 16 | of measurements etc. are not protected by copyright, because they exist 17 | objectively and therefore cannot be created. The same applies to ideas, 18 | mathematical formulas, elements of folklore etc. While quantitative data are 19 | usually not protected by copyright, qualitative data (as their creation 20 | involve some intellectual judgment) or language data are usually 21 | copyrightable. 22 |
23 |24 | Apart from copyright in the data itself, a compilation of data (a dataset) may 25 | also be protected by copyright as an original work. It is the case when the 26 | selection and arrangement of the dataset involves some degree of intellectual 27 | creation or choice. This is not the case when the guiding principle of the 28 | collection is exhaustivity and/or completeness. For example, while My 29 | favorite works of William Shakespeare will most likely be an original 30 | collection, Complete works of William Shakespeare will not, as it leaves 31 | no room for personal creativity. 32 |
33 |34 | The investment (of money and/or labor) into the making of the dataset is 35 | irrelevant from the point of view of copyright law; however, a substantial 36 | investment into the creation of a database may attract a specific kind of 37 | protection, the sui generis database right. If your data and your dataset are 38 | not original, but you made a substantial investment into the making of a 39 | database, you can still benefit from legal protection (in such a case, answer 40 | YES to this question). 41 |
42 |Answer Yes if ...
43 |answer No if ...
50 |58 | copyright – protects original works or original compilations of works 59 |
60 |61 | sui generis database rights – protects substantial investment into the making of a database 62 |
63 | """ 64 | 'licensed under a public license': """ 65 |66 | By licensed data we understand data available under a public license, such 67 | as Creative Commons or ODC licenses. If you have a bespoke license for the 68 | data (i.e. a license drafted for a specific contractual agreement, such as 69 | between a publisher and a research institution), contact our legal help desk. 70 |
71 | """ 72 | 'Public Domain': """ 73 |74 | Public Domain is a category including works that are not protected by 75 | copyright (such as raw facts, ideas) or that are no longer protected by 76 | copyright (copyright expires 70 years after the death of the author). In many 77 | jurisdictions, some official texts such as court decisions or statutes are 78 | also regarded as part of the public domain. 79 |
80 | """ 81 | 'additional permission': """ 82 |83 | In order to be able to deposit your data in our repository, you will have to 84 | contact the copyright holder (usually the publisher or the author) and ask him 85 | for a written permission to do so. Our legal help desk will help you draft the 86 | permission. We will also tell you what to do if you cannot identify the 87 | copyright holder. 88 |
89 | """ 90 | 'derivative works': """ 91 |92 | Derivative works are works that are derived from or based upon an original 93 | work and in which the original work is translated, altered, arranged, 94 | transformed, or otherwise modified. This category does not include parodies. 95 |
96 |97 | Please note that the use of language resources consists of making derivative 98 | works. If you do not allow others to build on your work, it will be of very 99 | little use for the community. 100 |
101 | """ 102 | 'commercial use': """ 103 |104 | Commercial use is a use that is primarily intended for or directed towards 105 | commercial advantage or monetary compensation. 106 |
107 |108 | Please note that the meaning of this term is not entirely clear (although it 109 | seems to be generally agreed upon that academic research, even carried out by 110 | professional researchers, is not commercial use) and if you choose this 111 | restriction, it may have a chilling effect on the re-use of your resource by 112 | some projects (public-private partnerships). 113 |
114 | """ 115 | 'attribute': """ 116 |117 | It is your moral right to have your work attributed to you (i.e. your name 118 | mentioned every time someone uses your work). However, be aware of the fact 119 | that the attribution requirement in Creative Commons licenses is more extended 120 | than just mentioning your name. 121 |
122 |123 | In fact, the attribution clause in Creative Commons licenses obliges the user 124 | to mention a whole set of information (identity of the creator, a copyright 125 | notice, a reference to the chosen CC license and a hyperlink to its text, a 126 | disclaimer of warranties, an indication of any modifications made to the 127 | original work and even a hyperlink to the work itself). This may lead to a 128 | phenomenon known as attribution stacking, which will make your work 129 | difficult to compile with other works. 130 |
131 | """ 132 | 133 | ExplanationsTerms = _.keys(Explanations) 134 | 135 | addExplanations = (text) -> 136 | for term in ExplanationsTerms 137 | index = text.indexOf(term) 138 | if ( index >= 0 ) 139 | text = text.substring(0,index) + 140 | '' + 141 | text.substring(index, index + term.length) + 142 | '' + text.substring(index + term.length) 143 | return text 144 | 145 | explanationTooltips = (scope, container) -> 146 | $('.ls-term', scope).each -> 147 | $el = $(this) 148 | term = $el.html() 149 | return unless Explanations[term] 150 | new Tooltip($('').addClass('ls-term-tooltip').html(Explanations[term]), $el, { 151 | 'container': container 152 | position: 'bottom' 153 | }) 154 | return 155 | return 156 | 157 | 158 | module.exports = 159 | EVENT_NS: EVENT_NS 160 | Explanations: Explanations 161 | ExplanationsTerms: ExplanationsTerms 162 | addExplanations: addExplanations 163 | explanationTooltips: explanationTooltips 164 | -------------------------------------------------------------------------------- /src/modal.less: -------------------------------------------------------------------------------- 1 | // Prevent overflow on HTML element 2 | html { 3 | overflow-y: scroll; 4 | } 5 | 6 | 7 | .has-overlay { 8 | overflow: hidden; 9 | 10 | > body { 11 | height: 100%; 12 | overflow-y: scroll; 13 | } 14 | 15 | 16 | @media screen and (max-width: @modal-small-breakpoint) { 17 | > body { 18 | overflow: hidden; 19 | } 20 | } 21 | } 22 | 23 | 24 | .modal() { 25 | // Hide initially 26 | -webkit-transform: translate(0, 100%); 27 | -moz-transform: translate(0, 100%); 28 | -o-transform: translate(0, 100%); 29 | -ms-transform: translate(0, 100%); 30 | transform: translate(0, 100%); 31 | -webkit-transform: translate3d(0, 100%, 0); // iOS 32 | transform: translate3d(0, 100%, 0); 33 | 34 | // Maintain a fixed position 35 | position: fixed; 36 | top: 0; 37 | left: 0; 38 | right: 0; 39 | bottom: 0; 40 | z-index: @modal-layer; 41 | width: 0; 42 | height: 0; 43 | overflow: hidden; 44 | opacity: 0; 45 | 46 | 47 | // Show modal when requested 48 | &:target, 49 | &.is-active { 50 | -webkit-transform: translate(0, 0); 51 | -moz-transform: translate(0, 0); 52 | -o-transform: translate(0, 0); 53 | -ms-transform: translate(0, 0); 54 | transform: translate(0, 0); 55 | 56 | width: auto; 57 | height: auto; 58 | 59 | opacity: 1; 60 | } 61 | 62 | // Internet Explorer 8 63 | display: none\9; 64 | 65 | 66 | &.is-active { 67 | display: block\9; 68 | height: 100%\9; 69 | width: 100%\9; 70 | } 71 | 72 | 73 | // Overwrite IE8 hack for IE9 and IE10 74 | &:target, 75 | &.is-active { 76 | display: block\9; 77 | } 78 | 79 | 80 | // Content Area 81 | .ls-modal { 82 | position: absolute; 83 | top: 50px; 84 | left: 50%; 85 | z-index: @modal-layer+20; 86 | //margin-left: (@modal-max-width / 2) * -1; 87 | //width: @modal-max-width; 88 | width: 100%; 89 | overflow-x: hidden; 90 | 91 | -webkit-overflow-scrolling: touch; // Native style momentum scrolling 92 | 93 | border-radius: @modal-border-radius; 94 | background: @modal-inner-background; 95 | .box-shadow(@modal-shadow-box); 96 | 97 | max-width: 100%; 98 | 99 | // -webkit-transition: max-width 0.25s linear, 100 | // margin-left 0.125s linear; 101 | // transition: max-width 0.25s linear, 102 | // margin-left 0.125s linear; 103 | 104 | // // This removes the scrollbar in lt IE9 105 | // @media \0screen\,screen\9 { 106 | // background: transparent; 107 | // } 108 | } 109 | 110 | 111 | // Content 112 | .ls-modal-content { 113 | position: relative; 114 | max-height: 200px; 115 | max-height: 50vh; 116 | overflow-x: hidden; 117 | overflow-y: auto; 118 | -webkit-overflow-scrolling: touch; 119 | 120 | border-bottom: 1px solid @modal-border-color; 121 | padding: 15px 1.2em; 122 | 123 | // // This removes the scrollbar in lt IE9 124 | // @media \0screen\,screen\9 { 125 | // overflow: visible; 126 | // } 127 | 128 | > * { 129 | max-width: 100%; 130 | } 131 | } 132 | 133 | // Header 134 | header { 135 | border-bottom: 1px solid @modal-border-color; 136 | background: @modal-header-background; 137 | padding: 20px 1.2em 10px 1.2em; 138 | 139 | > h2 { 140 | margin-top: 0; 141 | margin-bottom: 10px; 142 | } 143 | } 144 | 145 | // Footer 146 | footer { 147 | border-top: 1px solid lighten(@modal-border-color, 20); 148 | padding: 0 1.2em 18px; 149 | background: #f0f0f0; 150 | border-radius: @modal-border-radius; 151 | } 152 | 153 | 154 | // A close button 155 | .ls-modal-close { 156 | text-indent: -100px; 157 | 158 | display: block; 159 | height: 1px; // Prevent close element to appear 160 | clip: rect(0 0 0 0); 161 | overflow: hidden; 162 | 163 | &:focus:after { 164 | outline: 1px dotted; 165 | outline: -webkit-focus-ring-color auto 5px; 166 | } 167 | 168 | // Background as close 169 | &:before { 170 | content: ''; 171 | // Background for overlay: Data URI because of IE8 not supporting rgba 172 | //background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAEUlEQVQoz2NgeEYAjioYSQoAzOTmAXhPhyoAAAAASUVORK5CYII='); 173 | background: url('img/F7F7F7-0.9.png'); 174 | position: absolute; 175 | top: 0; 176 | left: 0; 177 | right: 0; 178 | bottom: 0; 179 | z-index: @modal-layer+10; 180 | } 181 | 182 | 183 | // Actual close button on modal 184 | &:after { 185 | content: '\00d7'; 186 | 187 | background: darken(@modal-header-background, 10%); 188 | border-radius: @modal-border-radius; 189 | padding: 2px 8px; 190 | 191 | font-size: 1.2em; 192 | text-decoration: none; 193 | text-indent: 0; 194 | 195 | position: absolute; 196 | top: 50px; 197 | right: 50%; 198 | z-index: @modal-layer+20; 199 | cursor: pointer; 200 | //margin-right: -(@modal-max-width / 2); 201 | } 202 | } 203 | 204 | 205 | // When screen isn't as wide as the modal anymore 206 | @media screen and (max-width: @modal-max-width + 40) { 207 | .ls-modal { 208 | width: auto; 209 | left: 20px; 210 | right: 20px; 211 | margin-left: 0; 212 | } 213 | 214 | .ls-modal-close { 215 | &:after { 216 | margin-right: 0 !important; 217 | right: 20px; 218 | } 219 | } 220 | } 221 | 222 | 223 | // For small screens adjust the modal 224 | @media screen and (max-width: @modal-small-breakpoint) { 225 | -webkit-transform: translate(0, 400px); // Use px to work around Android 2.3 bug 226 | -webkit-transform: translate3d(0, 100%, 0); // And overwrite px if 3D transforms are supported 227 | transform: translate3d(0, 100%, 0); 228 | 229 | -webkit-transition: opacity 1ms .25s; 230 | -moz-transition: opacity 1ms .25s; 231 | -o-transition: opacity 1ms .25s; 232 | -ms-transition: opacity 1ms .25s; 233 | transition: opacity 1ms .25s; 234 | 235 | display: block; 236 | bottom: auto; 237 | 238 | &:target, 239 | &.is-active { 240 | height: 100%; 241 | } 242 | 243 | 244 | &:before { 245 | content: ''; 246 | position: fixed; 247 | top: 0; 248 | left: 0; 249 | right: 0; 250 | z-index: @modal-layer+30; 251 | } 252 | 253 | 254 | .ls-modal { 255 | -webkit-box-sizing: border-box; 256 | -moz-box-sizing: border-box; 257 | box-sizing: border-box; 258 | 259 | top: 0; 260 | left: 0; 261 | right: 0; 262 | height: 100%; 263 | overflow: auto; 264 | } 265 | 266 | 267 | .ls-modal-content { 268 | max-height: none; 269 | 270 | // Prevent text from breaking modal in mobile view 271 | -ms-word-break: break-all; 272 | word-break: break-word; 273 | -webkit-hyphens: auto; 274 | -moz-hyphens: auto; 275 | hyphens: auto; 276 | } 277 | 278 | 279 | .ls-modal-close { 280 | right: auto; 281 | 282 | &:before { 283 | display: none; 284 | } 285 | 286 | &:after { 287 | top: 5px !important; 288 | right: 5px; 289 | left: auto; 290 | z-index: @modal-layer+40; 291 | margin-left: 0; 292 | } 293 | } 294 | } 295 | 296 | 297 | // For small heights 298 | @media screen and (max-height: 46em) and (min-width: @modal-small-breakpoint) { 299 | .ls-modal-content { 300 | max-height: 340px; 301 | max-height: 40vh; 302 | } 303 | } 304 | 305 | 306 | @media screen and (max-height: 36em) and (min-width: @modal-small-breakpoint) { 307 | .ls-modal-content { 308 | max-height: 265px; 309 | max-height: 30vh; 310 | } 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /cypress/e2e/license-selector.cy.js: -------------------------------------------------------------------------------- 1 | describe('License Selector E2E Tests', () => { 2 | 3 | beforeEach(() => { 4 | cy.visit('/') 5 | }) 6 | 7 | describe('Page Load and Basic Structure', () => { 8 | 9 | it('should load the page successfully', () => { 10 | cy.url().should('include', 'ufal.github.io/public-license-selector') 11 | cy.get('body').should('be.visible') 12 | }) 13 | 14 | it('should have correct page title', () => { 15 | cy.title().should('include', 'License Selector') 16 | }) 17 | 18 | it('should display the main heading', () => { 19 | cy.get('h1').should('contain', 'License Selector') 20 | }) 21 | 22 | it('should have the license selector links visible', () => { 23 | cy.contains('a', 'Click to open selector').should('exist') 24 | }) 25 | 26 | it('should load without console errors', () => { 27 | cy.visit('/', { 28 | onBeforeLoad(win) { 29 | cy.spy(win.console, 'error').as('consoleError') 30 | } 31 | }) 32 | cy.get('@consoleError').should('not.have.been.called') 33 | }) 34 | }) 35 | 36 | describe('Assets Loading', () => { 37 | 38 | it('should load jQuery from CDN', () => { 39 | cy.window().should('have.property', 'jQuery') 40 | cy.window().should('have.property', '$') 41 | }) 42 | 43 | it('should load lodash from CDN', () => { 44 | cy.window().should('have.property', '_') 45 | }) 46 | 47 | it('should load the license selector plugin', () => { 48 | cy.window().then((win) => { 49 | expect(win.$.fn).to.have.property('licenseSelector') 50 | }) 51 | }) 52 | 53 | it('should have CSS loaded correctly', () => { 54 | cy.get('.license-selector').should('have.css', 'position') 55 | }) 56 | }) 57 | 58 | describe('License Selector Modal - Auto-Open Behavior', () => { 59 | 60 | it('should automatically open the modal on page load', () => { 61 | cy.modalShouldBeVisible() 62 | }) 63 | 64 | it('should display modal with is-active class', () => { 65 | cy.get('.license-selector.is-active').should('exist') 66 | }) 67 | 68 | it('should display modal header with title', () => { 69 | cy.get('.ls-modal header h2').should('contain', 'Choose a License') 70 | }) 71 | 72 | it('should display modal body with content', () => { 73 | cy.get('.ls-modal-content').should('be.visible') 74 | cy.get('.ls-modal-content').children().should('have.length.gt', 0) 75 | }) 76 | 77 | it('should have a close button', () => { 78 | cy.get('.ls-modal-close').should('be.visible') 79 | }) 80 | 81 | it('should close modal when clicking close button', () => { 82 | cy.closeModal() 83 | cy.get('.license-selector').should('not.have.class', 'is-active') 84 | }) 85 | 86 | it('should reopen modal when clicking the selector link', () => { 87 | cy.closeModal() 88 | cy.reopenLicenseSelector() 89 | cy.modalShouldBeVisible() 90 | }) 91 | }) 92 | 93 | describe('Questionnaire Flow - Initial Question', () => { 94 | 95 | it('should display the first question on load', () => { 96 | cy.get('.ls-question-text').should('contain', 'deposit') 97 | }) 98 | 99 | it('should display answer buttons', () => { 100 | cy.get('.ls-question-answers button').should('have.length.gt', 0) 101 | }) 102 | 103 | it('should have Software and Data buttons', () => { 104 | cy.get('.ls-question-answers').should('contain', 'Software') 105 | cy.get('.ls-question-answers').should('contain', 'Data') 106 | }) 107 | 108 | it('should allow clicking Software button', () => { 109 | cy.clickAnswer('Software') 110 | cy.get('.ls-question-text').should('be.visible') 111 | }) 112 | 113 | it('should allow clicking Data button', () => { 114 | cy.clickAnswer('Data') 115 | cy.get('.ls-question-text').should('be.visible') 116 | }) 117 | }) 118 | 119 | describe('Questionnaire Flow - Data Path', () => { 120 | 121 | beforeEach(() => { 122 | cy.clickAnswer('Data') 123 | }) 124 | 125 | it('should show copyright question after selecting Data', () => { 126 | cy.get('.ls-question-text').should('contain', 'copyright') 127 | }) 128 | 129 | it('should have Yes/No buttons', () => { 130 | cy.get('.ls-question-answers button').should('contain', 'Yes') 131 | .and('contain', 'No') 132 | }) 133 | 134 | it('should navigate through the questionnaire', () => { 135 | cy.get('.ls-question-answers button').contains('Yes').click() 136 | 137 | cy.get('.ls-question').should('be.visible') 138 | }) 139 | 140 | it('should eventually show licenses', () => { 141 | cy.get('.ls-question-answers button').contains('No').click() 142 | 143 | cy.get('.ls-license-list').should('be.visible') 144 | }) 145 | }) 146 | 147 | describe('License List Display', () => { 148 | 149 | it('should display licenses after completing questionnaire', () => { 150 | cy.clickAnswer('Data') 151 | cy.get('.ls-question-answers button').contains('No').click() 152 | 153 | cy.licensesShouldBeVisible() 154 | }) 155 | 156 | it('should display license items with names', () => { 157 | cy.clickAnswer('Data') 158 | cy.get('.ls-question-answers button').contains('No').click() 159 | 160 | cy.get('.ls-license-list ul li h4').should('exist') 161 | }) 162 | 163 | it('should have clickable license items', () => { 164 | cy.clickAnswer('Data') 165 | cy.get('.ls-question-answers button').contains('No').click() 166 | 167 | cy.get('.ls-license-list ul li').first().should('be.visible') 168 | }) 169 | 170 | it('should display "See full text" links', () => { 171 | cy.clickAnswer('Data') 172 | cy.get('.ls-question-answers button').contains('No').click() 173 | 174 | cy.get('.ls-license-list .ls-button').should('exist') 175 | }) 176 | }) 177 | 178 | describe('Responsive Design', () => { 179 | 180 | it('should display correctly on desktop (1920x1080)', () => { 181 | cy.viewport(1920, 1080) 182 | cy.visit('/') 183 | 184 | cy.modalShouldBeVisible() 185 | 186 | cy.get('.ls-question').should('be.visible') 187 | 188 | cy.get('.ls-question-answers button').should('be.visible') 189 | }) 190 | }) 191 | 192 | describe('Performance', () => { 193 | 194 | it('should load the DOMContentLoaded event within acceptable time', () => { 195 | cy.visit('/') 196 | cy.window().its('performance.timing').then((timing) => { 197 | const domContentLoaded = timing.domContentLoadedEventEnd - timing.navigationStart 198 | expect(domContentLoaded).to.be.lessThan(3000) 199 | }) 200 | }) 201 | 202 | it('should open modal quickly (auto-opens)', () => { 203 | cy.visit('/') 204 | cy.modalShouldBeVisible() 205 | }) 206 | 207 | it('should respond to clicks quickly', () => { 208 | cy.clickAnswer('Data') 209 | cy.get('.ls-question-text').should('be.visible') 210 | }) 211 | }) 212 | 213 | describe('Integration with Page', () => { 214 | 215 | it('should handle multiple selector instances', () => { 216 | cy.get('p a').filter(':contains("Click to open selector")').should('have.length.gte', 1) 217 | }) 218 | 219 | it('should support modified options selector', () => { 220 | cy.contains('Click to open selector with modified options').should('exist') 221 | }) 222 | }) 223 | 224 | describe('Accessibility', () => { 225 | 226 | it('should have proper ARIA attributes on modal', () => { 227 | cy.get('.license-selector').should('have.attr', 'role', 'dialog') 228 | }) 229 | 230 | it('should have aria-hidden attribute', () => { 231 | cy.get('.license-selector').should('have.attr', 'aria-hidden') 232 | }) 233 | 234 | it('should have tabindex on modal', () => { 235 | cy.get('.license-selector').should('have.attr', 'tabindex', '-1') 236 | }) 237 | 238 | it('should have focusable buttons', () => { 239 | cy.get('.ls-question-answers button').first().should('be.visible') 240 | .and('not.be.disabled') 241 | }) 242 | }) 243 | }) 244 | -------------------------------------------------------------------------------- /src/img/licenses/eclipse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/img/licenses/mozilla.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 101 | -------------------------------------------------------------------------------- /src/license-selector.less: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'mixins'; 3 | @import 'modal'; 4 | @import 'tooltip'; 5 | 6 | /* Font icons by http://fontello.com/ */ 7 | 8 | @font-face { 9 | font-family: 'ls-icons'; 10 | src: url('fonts/ls-icons.eot') format('embedded-opentype'), 11 | url('fonts/ls-icons.svg') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | @font-face { 16 | font-family: 'ls-icons'; 17 | src: url('fonts/ls-icons.woff') format('woff'), 18 | url('fonts/ls-icons.ttf') format('truetype'); 19 | } 20 | 21 | .license-selector { 22 | 23 | .modal(); 24 | 25 | font: 14px/1.4 Helvetica Neue, sans-serif; 26 | color: @textColor; 27 | line-height: 1.3; 28 | 29 | h2, h3, h4 { 30 | font-weight: 500; 31 | line-height: 1.1; 32 | } 33 | 34 | h2 { 35 | font-size: 24px; 36 | } 37 | 38 | h3 { 39 | font-size: 22px; 40 | } 41 | 42 | h4 { 43 | font-size: 20px; 44 | } 45 | 46 | p { 47 | margin: 0 0 10px; 48 | } 49 | 50 | button, a.ls-button { 51 | display: inline-block; 52 | padding: 4px 12px; 53 | margin-bottom: 0; // For input.btn 54 | font-size: @baseFontSize; 55 | line-height: @baseLineHeight; 56 | text-decoration: none; 57 | text-align: center; 58 | vertical-align: middle; 59 | cursor: pointer; 60 | .button-background(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); 61 | border: 1px solid @btnBorder; 62 | *border: 0; // Remove the border to prevent IE7's black border on input:focus 63 | border-bottom-color: darken(@btnBorder, 10%); 64 | .border-radius(@baseBorderRadius); 65 | .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); 66 | 67 | // Hover/focus state 68 | &:hover, 69 | &:focus { 70 | color: @grayDark; 71 | text-decoration: none; 72 | background-position: 0 -15px; 73 | 74 | // transition is only when going to hover/focus, otherwise the background 75 | // behind the gradient (there for IE<=9 fallback) gets mismatched 76 | .transition(background-position .1s linear); 77 | } 78 | 79 | // Active state 80 | &.active, 81 | &:active { 82 | background-image: none; 83 | outline: 0; 84 | .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); 85 | } 86 | 87 | // Disabled state 88 | &.disabled, 89 | &[disabled] { 90 | cursor: default; 91 | background-image: none; 92 | .opacity(65); 93 | .box-shadow(none); 94 | } 95 | } 96 | 97 | .icon(@content) { 98 | &:before { 99 | content: @content; 100 | font-family: "ls-icons"; 101 | font-style: normal; 102 | font-weight: normal; 103 | speak: none; 104 | 105 | display: inline-block; 106 | text-decoration: inherit; 107 | width: 1em; 108 | margin-right: .2em; 109 | text-align: center; 110 | /* opacity: .8; */ 111 | 112 | /* For safety - reset parent styles, that can break glyph codes*/ 113 | font-variant: normal; 114 | text-transform: none; 115 | 116 | /* fix buttons height, for twitter bootstrap */ 117 | line-height: 1em; 118 | 119 | /* Animation center compensation - margins should be symmetric */ 120 | /* remove if not needed */ 121 | margin-left: .2em; 122 | 123 | /* you can be more comfortable with increased icons size */ 124 | /* font-size: 120%; */ 125 | 126 | /* Uncomment for 3D effect */ 127 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ 128 | } 129 | } 130 | 131 | .icon-left { .icon('\e800'); } /* '' */ 132 | .icon-right { .icon('\e801'); } /* '' */ 133 | .icon-ccw { .icon('\e802'); } /* '' */ 134 | 135 | .ls-license-name { 136 | display: block; 137 | } 138 | 139 | .ls-history { 140 | height: 20px; 141 | margin-bottom: 15px; 142 | } 143 | 144 | .ls-history > button { 145 | margin: 0 2px; 146 | } 147 | 148 | .ls-history > button:first-child { 149 | margin: 0 2px 0 0; 150 | } 151 | 152 | .ls-restart, .ls-history-next, .ls-history-prev { 153 | padding: @paddingSmall; 154 | font-size: @fontSizeSmall; 155 | .border-radius(@borderRadiusSmall); 156 | } 157 | 158 | .ls-history-progress, .ls-history-next, .ls-history-prev, .ls-restart { 159 | float: left; 160 | } 161 | 162 | .ls-history .ls-history-progress button { 163 | padding: @paddingSmall; 164 | padding-left: 3px; 165 | padding-right: 3px; 166 | margin: 0 1px; 167 | font-size: @fontSizeSmall; 168 | .border-radius(@borderRadiusSmall); 169 | 170 | &.ls-active { 171 | .button-background(@btnPrimaryBackground, @btnPrimaryBackgroundHighlight); 172 | } 173 | } 174 | 175 | .ls-question { 176 | padding: 15px; 177 | border-radius: 4px; 178 | background: #eee; 179 | /*margin-bottom: 10px;*/ 180 | border: 1px solid #ccc; 181 | } 182 | 183 | .ls-term { 184 | cursor: help; 185 | border-bottom: 1px dotted #777; 186 | } 187 | 188 | .ls-question-answers button { 189 | display: inline-block; 190 | margin-right: 10px; 191 | } 192 | 193 | .ls-question-options { 194 | margin-bottom: 5px; 195 | } 196 | 197 | .ls-question-options ul { 198 | list-style: none; 199 | padding: 0; 200 | margin: 0; 201 | } 202 | 203 | .ls-question-options label { 204 | position: relative; 205 | font-weight: normal; 206 | display: inline-block; 207 | margin-bottom: 5px; 208 | padding-left: 20px; 209 | cursor: pointer; 210 | } 211 | 212 | .ls-question-options input[type=checkbox] { 213 | position: absolute; 214 | margin: 4px 0 0 -20px; 215 | padding: 0; 216 | } 217 | 218 | .ls-question-error { 219 | color: #a94442; 220 | background-color: #f2dede; 221 | border-color: #ebccd1; 222 | padding: 15px; 223 | margin-bottom: 20px; 224 | border: 1px solid transparent; 225 | border-radius: 4px; 226 | } 227 | 228 | .ls-question-error h4, .ls-not-found h4 { 229 | color: #a94442; 230 | font-weight: bold; 231 | margin: 5px 0 5px 0; 232 | } 233 | 234 | /* Taken from bootstrap http://getbootstrap.com/css/#forms */ 235 | 236 | .ls-search { 237 | padding: 10px 0 0 0; 238 | 239 | input { 240 | display: block; 241 | width: 100%; 242 | height: 34px; 243 | padding: 6px 12px; 244 | margin: 0; 245 | font-size: 14px; 246 | line-height: 1.42857143; 247 | color: #555; 248 | background-color: #fff; 249 | background-image: none; 250 | border: 1px solid #ccc; 251 | border-radius: 4px; 252 | .box-shadow(inset 0 1px 1px rgba(0,0,0,0.075)); 253 | .transition(border-color ease-in-out 0.15s,-webkit-box-shadow ease-in-out 0.15s); 254 | box-sizing: border-box; 255 | 256 | &:focus { 257 | border-color: #3db3e5; 258 | outline: 0; 259 | .box-shadow(inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)); 260 | } 261 | } 262 | } 263 | 264 | .ls-license-list > ul { 265 | list-style: none; 266 | padding: 0; 267 | margin: 0; 268 | } 269 | 270 | .ls-license-list > ul > li { 271 | border: 1px solid #ddd; 272 | border-radius: 4px; 273 | padding: 5px 10px; 274 | margin: 5px 0; 275 | cursor: pointer; 276 | position: relative; 277 | } 278 | 279 | .ls-license-list h4 { 280 | position: relative; 281 | margin: 5px 0 5px 0; 282 | padding: 0; 283 | font-size: 18px; 284 | line-height: 1.5; 285 | } 286 | 287 | .ls-license-list li p { 288 | color: #777; 289 | } 290 | 291 | .ls-license-list li button, .ls-license-list li .ls-button { 292 | display: none; 293 | padding: 1px 5px; 294 | font-size: 12px; 295 | line-height: 1.5; 296 | margin: 0 0 2px 7px; 297 | vertical-align: middle; 298 | } 299 | 300 | .ls-license-list li:hover button, .ls-license-list li.ls-active button, .ls-license-list li:hover .ls-button, .ls-license-list li.ls-active .ls-button { 301 | display: inline-block; 302 | } 303 | 304 | .ls-license-list li:hover p, .ls-license-list li.ls-active p { 305 | color: inherit; 306 | } 307 | 308 | .ls-license-list li .ls-confirm, .ls-license-list li.ls-active .ls-select { 309 | display: none; 310 | } 311 | 312 | .ls-license-list li.ls-active { 313 | border: 2px solid @linkColor; 314 | } 315 | 316 | .ls-license-list li.ls-active .ls-confirm, .ls-license-list li .ls-select { 317 | display: inline-block; 318 | } 319 | 320 | .ls-labels:after { 321 | content:""; 322 | display:table; 323 | clear:both; 324 | } 325 | 326 | .ls-label { 327 | padding: 2px 3px; 328 | margin: 0 4px 0 0; 329 | font-weight: 500; 330 | float: left; 331 | } 332 | 333 | .ls-label-public { 334 | color: #5cb811; 335 | border-radius: 4px; 336 | border: 1px solid #5cb811; 337 | background-color: #dff0d8; 338 | } 339 | 340 | .ls-label-aca { 341 | color: #ffab23; 342 | border-radius: 4px; 343 | border: 1px solid #ffab23; 344 | background-color: #fcf8e3; 345 | } 346 | 347 | .ls-label-res { 348 | color: #c62d1f; 349 | border-radius: 4px; 350 | border: 1px solid #c62d1f; 351 | background-color: #f2dede; 352 | } 353 | 354 | .label-icon(@icon; @width : 22px) { 355 | background-image: url("img/licenses/@{icon}.png"); 356 | width: @width - 6; 357 | height: 18px; 358 | background-position: center; 359 | background-size: @width 22px; 360 | background-repeat: no-repeat; 361 | } 362 | 363 | .ls-icon-pd { .label-icon('pd'); } 364 | .ls-icon-cc { .label-icon('cc'); } 365 | .ls-icon-zero { .label-icon('zero'); } 366 | .ls-icon-by { .label-icon('by'); } 367 | .ls-icon-sa { .label-icon('sa'); } 368 | .ls-icon-nd { .label-icon('nd'); } 369 | .ls-icon-nc { .label-icon('nc'); } 370 | .ls-icon-perl { .label-icon('perl'); } 371 | .ls-icon-osi { .label-icon('osi', 25px); } 372 | .ls-icon-gpl { .label-icon('gpl'); } 373 | .ls-icon-gpl3 { .label-icon('gpl3', 82px); } 374 | .ls-icon-agpl3 { .label-icon('agpl3', 82px); } 375 | .ls-icon-lgpl { .label-icon('lgpl'); } 376 | .ls-icon-lgpl3 { .label-icon('lgpl3', 82px); } 377 | .ls-icon-copyleft { .label-icon('copyleft'); } 378 | .ls-icon-mozilla { .label-icon('mozilla', 31px); } 379 | .ls-icon-mit { .label-icon('mit'); } 380 | .ls-icon-bsd { .label-icon('bsd'); } 381 | .ls-icon-apache { .label-icon('apache', 86px); } 382 | .ls-icon-eclipse { .label-icon('eclipse', 102px); } 383 | .ls-icon-opendata { .label-icon('opendata', 117px); } 384 | } 385 | -------------------------------------------------------------------------------- /src/variables.less: -------------------------------------------------------------------------------- 1 | // This is default Boostrap 2 theme 2 | // 3 | // Variables 4 | // -------------------------------------------------- 5 | 6 | // Modal 7 | 8 | // Modal General Styles 9 | @modal-max-width: 650px; 10 | @modal-border-radius: 2px; 11 | @modal-small-breakpoint: 30em; 12 | 13 | // Modal Plain Screen Styles 14 | @modal-plain-screen-overlay: #fff; 15 | 16 | // Set high z-index to appear above all other content 17 | @modal-layer: 800; 18 | 19 | // Color configuration 20 | @modal-border-color: #ddd; 21 | @modal-inner-background: #fff; 22 | @modal-color: #222; 23 | @modal-mobile-header: #27aae2; 24 | 25 | @modal-shadow-box: 0 0 30px rgba(0,0,0,0.6); 26 | @modal-header-background: #eee; 27 | 28 | // Global values 29 | // -------------------------------------------------- 30 | 31 | 32 | // Grays 33 | // ------------------------- 34 | @black: #000; 35 | @grayDarker: #222; 36 | @grayDark: #333; 37 | @gray: #555; 38 | @grayLight: #999; 39 | @grayLighter: #eee; 40 | @white: #fff; 41 | 42 | 43 | // Accent colors 44 | // ------------------------- 45 | @blue: #049cdb; 46 | @blueDark: #0064cd; 47 | @green: #46a546; 48 | @red: #9d261d; 49 | @yellow: #ffc40d; 50 | @orange: #f89406; 51 | @pink: #c3325f; 52 | @purple: #7a43b6; 53 | 54 | 55 | // Scaffolding 56 | // ------------------------- 57 | @bodyBackground: @white; 58 | @textColor: @grayDark; 59 | 60 | 61 | // Links 62 | // ------------------------- 63 | @linkColor: #08c; 64 | @linkColorHover: darken(@linkColor, 15%); 65 | 66 | 67 | // Typography 68 | // ------------------------- 69 | @sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; 70 | @serifFontFamily: Georgia, "Times New Roman", Times, serif; 71 | @monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; 72 | 73 | @baseFontSize: 14px; 74 | @baseFontFamily: @sansFontFamily; 75 | @baseLineHeight: 20px; 76 | @altFontFamily: @serifFontFamily; 77 | 78 | @headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily 79 | @headingsFontWeight: bold; // instead of browser default, bold 80 | @headingsColor: inherit; // empty to use BS default, @textColor 81 | 82 | 83 | // Component sizing 84 | // ------------------------- 85 | // Based on 14px font-size and 20px line-height 86 | 87 | @fontSizeLarge: @baseFontSize * 1.25; // ~18px 88 | @fontSizeSmall: @baseFontSize * 0.85; // ~12px 89 | @fontSizeMini: @baseFontSize * 0.75; // ~11px 90 | 91 | @paddingLarge: 11px 19px; // 44px 92 | @paddingSmall: 2px 10px; // 26px 93 | @paddingMini: 0 6px; // 22px 94 | 95 | @baseBorderRadius: 4px; 96 | @borderRadiusLarge: 6px; 97 | @borderRadiusSmall: 3px; 98 | 99 | 100 | // Tables 101 | // ------------------------- 102 | @tableBackground: transparent; // overall background-color 103 | @tableBackgroundAccent: #f9f9f9; // for striping 104 | @tableBackgroundHover: #f5f5f5; // for hover 105 | @tableBorder: #ddd; // table and cell border 106 | 107 | // Buttons 108 | // ------------------------- 109 | @btnBackground: @white; 110 | @btnBackgroundHighlight: darken(@white, 10%); 111 | @btnBorder: #ccc; 112 | 113 | @btnPrimaryBackground: @linkColor; 114 | @btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%); 115 | 116 | @btnInfoBackground: #5bc0de; 117 | @btnInfoBackgroundHighlight: #2f96b4; 118 | 119 | @btnSuccessBackground: #62c462; 120 | @btnSuccessBackgroundHighlight: #51a351; 121 | 122 | @btnWarningBackground: lighten(@orange, 15%); 123 | @btnWarningBackgroundHighlight: @orange; 124 | 125 | @btnDangerBackground: #ee5f5b; 126 | @btnDangerBackgroundHighlight: #bd362f; 127 | 128 | @btnInverseBackground: #444; 129 | @btnInverseBackgroundHighlight: @grayDarker; 130 | 131 | 132 | // Forms 133 | // ------------------------- 134 | @inputBackground: @white; 135 | @inputBorder: #ccc; 136 | @inputBorderRadius: @baseBorderRadius; 137 | @inputDisabledBackground: @grayLighter; 138 | @formActionsBackground: #f5f5f5; 139 | @inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border 140 | 141 | 142 | // Dropdowns 143 | // ------------------------- 144 | @dropdownBackground: @white; 145 | @dropdownBorder: rgba(0,0,0,.2); 146 | @dropdownDividerTop: #e5e5e5; 147 | @dropdownDividerBottom: @white; 148 | 149 | @dropdownLinkColor: @grayDark; 150 | @dropdownLinkColorHover: @white; 151 | @dropdownLinkColorActive: @white; 152 | 153 | @dropdownLinkBackgroundActive: @linkColor; 154 | @dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; 155 | 156 | 157 | 158 | // COMPONENT VARIABLES 159 | // -------------------------------------------------- 160 | 161 | 162 | // Z-index master list 163 | // ------------------------- 164 | // Used for a bird's eye view of components dependent on the z-axis 165 | // Try to avoid customizing these :) 166 | @zindexDropdown: 1000; 167 | @zindexPopover: 1010; 168 | @zindexTooltip: 1030; 169 | @zindexFixedNavbar: 1030; 170 | @zindexModalBackdrop: 1040; 171 | @zindexModal: 1050; 172 | 173 | 174 | // Sprite icons path 175 | // ------------------------- 176 | @iconSpritePath: "../img/glyphicons-halflings.png"; 177 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 178 | 179 | 180 | // Input placeholder text color 181 | // ------------------------- 182 | @placeholderText: @grayLight; 183 | 184 | 185 | // Hr border color 186 | // ------------------------- 187 | @hrBorder: @grayLighter; 188 | 189 | 190 | // Horizontal forms & lists 191 | // ------------------------- 192 | @horizontalComponentOffset: 180px; 193 | 194 | 195 | // Wells 196 | // ------------------------- 197 | @wellBackground: #f5f5f5; 198 | 199 | 200 | // Navbar 201 | // ------------------------- 202 | @navbarCollapseWidth: 979px; 203 | @navbarCollapseDesktopWidth: @navbarCollapseWidth + 1; 204 | 205 | @navbarHeight: 40px; 206 | @navbarBackgroundHighlight: #ffffff; 207 | @navbarBackground: darken(@navbarBackgroundHighlight, 5%); 208 | @navbarBorder: darken(@navbarBackground, 12%); 209 | 210 | @navbarText: #777; 211 | @navbarLinkColor: #777; 212 | @navbarLinkColorHover: @grayDark; 213 | @navbarLinkColorActive: @gray; 214 | @navbarLinkBackgroundHover: transparent; 215 | @navbarLinkBackgroundActive: darken(@navbarBackground, 5%); 216 | 217 | @navbarBrandColor: @navbarLinkColor; 218 | 219 | // Inverted navbar 220 | @navbarInverseBackground: #111111; 221 | @navbarInverseBackgroundHighlight: #222222; 222 | @navbarInverseBorder: #252525; 223 | 224 | @navbarInverseText: @grayLight; 225 | @navbarInverseLinkColor: @grayLight; 226 | @navbarInverseLinkColorHover: @white; 227 | @navbarInverseLinkColorActive: @navbarInverseLinkColorHover; 228 | @navbarInverseLinkBackgroundHover: transparent; 229 | @navbarInverseLinkBackgroundActive: @navbarInverseBackground; 230 | 231 | @navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); 232 | @navbarInverseSearchBackgroundFocus: @white; 233 | @navbarInverseSearchBorder: @navbarInverseBackground; 234 | @navbarInverseSearchPlaceholderColor: #ccc; 235 | 236 | @navbarInverseBrandColor: @navbarInverseLinkColor; 237 | 238 | 239 | // Pagination 240 | // ------------------------- 241 | @paginationBackground: #fff; 242 | @paginationBorder: #ddd; 243 | @paginationActiveBackground: #f5f5f5; 244 | 245 | 246 | // Hero unit 247 | // ------------------------- 248 | @heroUnitBackground: @grayLighter; 249 | @heroUnitHeadingColor: inherit; 250 | @heroUnitLeadColor: inherit; 251 | 252 | 253 | // Form states and alerts 254 | // ------------------------- 255 | @warningText: #c09853; 256 | @warningBackground: #fcf8e3; 257 | @warningBorder: darken(spin(@warningBackground, -10), 3%); 258 | 259 | @errorText: #b94a48; 260 | @errorBackground: #f2dede; 261 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 262 | 263 | @successText: #468847; 264 | @successBackground: #dff0d8; 265 | @successBorder: darken(spin(@successBackground, -10), 5%); 266 | 267 | @infoText: #3a87ad; 268 | @infoBackground: #d9edf7; 269 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 270 | 271 | 272 | // Tooltips and popovers 273 | // ------------------------- 274 | @tooltipColor: #fff; 275 | @tooltipBackground: #000; 276 | @tooltipArrowWidth: 5px; 277 | @tooltipArrowColor: @tooltipBackground; 278 | 279 | @popoverBackground: #fff; 280 | @popoverArrowWidth: 10px; 281 | @popoverArrowColor: #fff; 282 | @popoverTitleBackground: darken(@popoverBackground, 3%); 283 | 284 | // Special enhancement for popovers 285 | @popoverArrowOuterWidth: @popoverArrowWidth + 1; 286 | @popoverArrowOuterColor: rgba(0,0,0,.25); 287 | 288 | 289 | 290 | // GRID 291 | // -------------------------------------------------- 292 | 293 | 294 | // Default 940px grid 295 | // ------------------------- 296 | @gridColumns: 12; 297 | @gridColumnWidth: 60px; 298 | @gridGutterWidth: 20px; 299 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 300 | 301 | // 1200px min 302 | @gridColumnWidth1200: 70px; 303 | @gridGutterWidth1200: 30px; 304 | @gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); 305 | 306 | // 768px-979px 307 | @gridColumnWidth768: 42px; 308 | @gridGutterWidth768: 20px; 309 | @gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); 310 | 311 | 312 | // Fluid grid 313 | // ------------------------- 314 | @fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); 315 | @fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); 316 | 317 | // 1200px min 318 | @fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); 319 | @fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); 320 | 321 | // 768px-979px 322 | @fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); 323 | @fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); 324 | --------------------------------------------------------------------------------