├── .circleci
└── config.yml
├── .gitattributes
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── all.js
├── code-of-conduct.md
├── demo
├── _charts.js
├── app.js
├── demo.js
├── demo.tag
├── index.html
├── static
│ ├── img
│ │ ├── amex.png
│ │ ├── diners_club.png
│ │ ├── discover.png
│ │ ├── example.png
│ │ ├── first.jpg
│ │ ├── jcb.png
│ │ ├── mastercard.png
│ │ ├── second.jpg
│ │ ├── third.jpg
│ │ └── visa.png
│ ├── inc.html
│ ├── inc.md
│ ├── inc2.html
│ └── tab.html
└── style.css
├── dependencies
└── js
│ ├── iframify.js
│ ├── riot+compiler-2.6.9.min.js
│ └── riot+compiler-3.13.2.min.js
├── dist
├── rg-alerts
│ └── rg-alerts.js
├── rg-bubble
│ └── rg-bubble.js
├── rg-chart
│ └── rg-chart.js
├── rg-code
│ └── rg-code.js
├── rg-credit-card
│ └── rg-credit-card-number.js
├── rg-date
│ └── rg-date.js
├── rg-drawer
│ └── rg-drawer.js
├── rg-ga
│ └── rg-ga.js
├── rg-iframify
│ └── rg-iframify.js
├── rg-include
│ └── rg-include.js
├── rg-map
│ └── rg-map.js
├── rg-markdown
│ └── rg-markdown.js
├── rg-modal
│ └── rg-modal.js
├── rg-pagination
│ └── rg-pagination.js
├── rg-phone-sim
│ └── rg-phone-sim.js
├── rg-placeholdit
│ └── rg-placeholdit.js
├── rg-raw
│ └── rg-raw.js
├── rg-select
│ └── rg-select.js
├── rg-tabs
│ └── rg-tabs.js
├── rg-tags
│ └── rg-tags.js
├── rg-toast
│ └── rg-toasts.js
├── rg-toggle
│ └── rg-toggle.js
├── rg-unsplash
│ └── rg-unsplash.js
├── rg.js
└── rg.min.js
├── karma.conf.js
├── package.json
├── tags
├── rg-alerts
│ ├── rg-alerts.blank.spec.js
│ ├── rg-alerts.spec.js
│ └── rg-alerts.tag
├── rg-audio
│ └── rg-audio.tag
├── rg-bubble
│ ├── rg-bubble.spec.js
│ └── rg-bubble.tag
├── rg-chart
│ ├── rg-chart.spec.js
│ └── rg-chart.tag
├── rg-code
│ ├── rg-code.spec.js
│ └── rg-code.tag
├── rg-credit-card
│ ├── rg-credit-card-number.tag
│ └── rg-credit-card.spec.js
├── rg-date
│ ├── rg-date.spec.js
│ └── rg-date.tag
├── rg-drawer
│ ├── rg-drawer.spec.js
│ └── rg-drawer.tag
├── rg-ga
│ ├── rg-ga.spec.js
│ └── rg-ga.tag
├── rg-iframify
│ ├── rg-iframify.spec.js
│ └── rg-iframify.tag
├── rg-include
│ ├── rg-include.spec.js
│ └── rg-include.tag
├── rg-map
│ ├── rg-map.spec.js
│ └── rg-map.tag
├── rg-markdown
│ ├── rg-markdown.spec.js
│ └── rg-markdown.tag
├── rg-modal
│ ├── rg-modal.spec.js
│ └── rg-modal.tag
├── rg-pagination
│ ├── rg-pagination.spec.js
│ └── rg-pagination.tag
├── rg-phone-sim
│ ├── rg-phone-sim.spec.js
│ └── rg-phone-sim.tag
├── rg-placeholdit
│ ├── rg-placeholdit.spec.js
│ └── rg-placeholdit.tag
├── rg-raw
│ ├── rg-raw.spec.js
│ └── rg-raw.tag
├── rg-select
│ ├── rg-select.filter.spec.js
│ ├── rg-select.spec.js
│ └── rg-select.tag
├── rg-tabs
│ ├── rg-tabs.spec.js
│ └── rg-tabs.tag
├── rg-tags
│ ├── rg-tags.spec.js
│ └── rg-tags.tag
├── rg-toast
│ ├── rg-toasts.spec.js
│ └── rg-toasts.tag
├── rg-toggle
│ ├── rg-toggle.spec.js
│ └── rg-toggle.tag
└── rg-unsplash
│ ├── rg-unsplash.spec.js
│ └── rg-unsplash.tag
├── test-helpers.js
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/node:12.6-browsers
6 |
7 | working_directory: ~/repo
8 |
9 | steps:
10 | - checkout
11 |
12 | - restore_cache:
13 | keys:
14 | - v1-dependencies-{{ checksum "package.json" }}
15 | - v1-dependencies-
16 |
17 | - run: yarn install
18 |
19 | - save_cache:
20 | paths:
21 | - node_modules
22 | key: v1-dependencies-{{ checksum "package.json" }}
23 |
24 | - run: yarn test
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | dist/* binary
2 | dist/**/* binary
3 | yarn.lock binary
4 | demo/demo.js binary
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules/
3 | coverage
4 | npm-debug.log
5 |
6 | # parcel files
7 | _dist/
8 | .cache/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "5"
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | First of all, Pull Requests, suggestions or comments about RiotGear are all welcome and valued. To start contributing follow these steps:
4 |
5 | ## Step 1 - Fork the repo and install
6 |
7 | ```
8 | git clone https://github.com/riotgear/rg/
9 | cd rg
10 | yarn install
11 | yarn demo
12 | ```
13 |
14 | A local copy of the riotgear demo should now be running on http://localhost:1234 (port may vary if port is already in use)
15 |
16 | ## Step 2 - Write some code
17 |
18 | * You can modify existing tags or add a new tag in the `tags/rg-TAGNAME/rg-TAGNAME.tag` folder (where TAGNAME can be whatever you want). Then edit `all.js` to `import './tags/rg-TAGNAME/rg-TAGNAME`.
19 |
20 | * OPTIONAL - Modify `demo/demo.tag` to include a demo of your tag. This isn't required, but will help you develop and help whoever us understand your contribution.
21 |
22 | * OPTIONAL - Add a test file like `tags/rg-TAGNAME/rg-TAGNAME.spec.js`. You can look at the other tests for ideas for what to write. If you can't get the test runner working (we use puppeteer, which may not work on every machine), feel free to contact us. Tests are run with `yarn test` and an individual test can be run by modifying the spec file with `describe.only` or `it.only`.
23 |
24 | ## Step 3
25 |
26 | **Submit your Pull Request to our DEV branch** so that we can review the code before merging into master.
27 |
28 | ## Sit back
29 |
30 | At some point your changes will get merged in and we'll publish a new version of RiotGear! Yay!
31 |
32 | ### Code Conduct
33 |
34 | We're all friends! This project adheres to the [Contriubtor Covenant](./code-of-conduct.md). By participating, you are expected to honor this code.
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015
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 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://circleci.com/gh/chriscauley/rg)
2 |
3 | The open source component library for Riot.
4 |
5 | **http://riotgear.js.org**
6 |
7 |
8 |
9 |
10 |
11 | ## Contributing
12 |
13 | If you're interested in contributing or just in running the RiotGear repo locally, checkout the [Contribution Guide](CONTRIBUTING.md)
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 5.1.x | :white_check_mark: |
11 | | 5.0.x | :x: |
12 | | 4.0.x | :white_check_mark: |
13 | | < 4.0 | :x: |
14 |
15 | ## Reporting a Vulnerability
16 |
17 | Use this section to tell people how to report a vulnerability.
18 |
19 | Tell them where to go, how often they can expect to get an update on a
20 | reported vulnerability, what to expect if the vulnerability is accepted or
21 | declined, etc.
22 |
--------------------------------------------------------------------------------
/all.js:
--------------------------------------------------------------------------------
1 | import "./tags/rg-alerts/rg-alerts"
2 | import "./tags/rg-bubble/rg-bubble"
3 | import "./tags/rg-chart/rg-chart"
4 | import "./tags/rg-code/rg-code"
5 | import "./tags/rg-credit-card/rg-credit-card-number"
6 | import "./tags/rg-date/rg-date"
7 | import "./tags/rg-drawer/rg-drawer"
8 | import "./tags/rg-ga/rg-ga"
9 | import "./tags/rg-iframify/rg-iframify"
10 | import "./tags/rg-include/rg-include"
11 | import "./tags/rg-map/rg-map"
12 | import "./tags/rg-markdown/rg-markdown"
13 | import "./tags/rg-modal/rg-modal"
14 | import "./tags/rg-pagination/rg-pagination"
15 | import "./tags/rg-phone-sim/rg-phone-sim"
16 | import "./tags/rg-placeholdit/rg-placeholdit"
17 | import "./tags/rg-raw/rg-raw"
18 | import "./tags/rg-select/rg-select"
19 | import "./tags/rg-tabs/rg-tabs"
20 | import "./tags/rg-tags/rg-tags"
21 | import "./tags/rg-toast/rg-toasts"
22 | import "./tags/rg-toggle/rg-toggle"
23 | import "./tags/rg-unsplash/rg-unsplash"
--------------------------------------------------------------------------------
/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies within all project spaces, and it also applies when
49 | an individual is representing the project or its community in public spaces.
50 | Examples of representing a project or community include using an official
51 | project e-mail address, posting via an official social media account, or acting
52 | as an appointed representative at an online or offline event. Representation of
53 | a project may be further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
78 |
--------------------------------------------------------------------------------
/demo/_charts.js:
--------------------------------------------------------------------------------
1 | window._charts = {
2 | linechart: {
3 | type: 'line',
4 | data: {
5 | labels: ["January", "February", "March", "April", "May", "June", "July"],
6 | datasets: [{
7 | label: "My First dataset",
8 | fillColor: "rgba(220,220,220,0.2)",
9 | strokeColor: "rgba(220,220,220,1)",
10 | pointColor: "rgba(220,220,220,1)",
11 | pointStrokeColor: "#fff",
12 | pointHighlightFill: "#fff",
13 | pointHighlightStroke: "rgba(220,220,220,1)",
14 | data: [65, 59, 80, 81, 56, 55, 40]
15 | }, {
16 | label: "My Second dataset",
17 | fillColor: "rgba(151,187,205,0.2)",
18 | strokeColor: "rgba(151,187,205,1)",
19 | pointColor: "rgba(151,187,205,1)",
20 | pointStrokeColor: "#fff",
21 | pointHighlightFill: "#fff",
22 | pointHighlightStroke: "rgba(151,187,205,1)",
23 | data: [28, 48, 40, 19, 86, 27, 90]
24 | }]
25 | }
26 | },
27 |
28 | barchart: {
29 | type: 'bar',
30 | data: {
31 | labels: ["January", "February", "March", "April", "May", "June", "July"],
32 | datasets: [{
33 | label: "My First dataset",
34 | fillColor: "rgba(220,220,220,0.5)",
35 | strokeColor: "rgba(220,220,220,0.8)",
36 | highlightFill: "rgba(220,220,220,0.75)",
37 | highlightStroke: "rgba(220,220,220,1)",
38 | data: [65, 59, 80, 81, 56, 55, 40]
39 | }, {
40 | label: "My Second dataset",
41 | fillColor: "rgba(151,187,205,0.5)",
42 | strokeColor: "rgba(151,187,205,0.8)",
43 | highlightFill: "rgba(151,187,205,0.75)",
44 | highlightStroke: "rgba(151,187,205,1)",
45 | data: [28, 48, 40, 19, 86, 27, 90]
46 | }]
47 | }
48 | },
49 |
50 | radarchart: {
51 | type: 'radar',
52 | data: {
53 | labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
54 | datasets: [{
55 | label: "My First dataset",
56 | fillColor: "rgba(220,220,220,0.2)",
57 | strokeColor: "rgba(220,220,220,1)",
58 | pointColor: "rgba(220,220,220,1)",
59 | pointStrokeColor: "#fff",
60 | pointHighlightFill: "#fff",
61 | pointHighlightStroke: "rgba(220,220,220,1)",
62 | data: [65, 59, 90, 81, 56, 55, 40]
63 | }, {
64 | label: "My Second dataset",
65 | fillColor: "rgba(151,187,205,0.2)",
66 | strokeColor: "rgba(151,187,205,1)",
67 | pointColor: "rgba(151,187,205,1)",
68 | pointStrokeColor: "#fff",
69 | pointHighlightFill: "#fff",
70 | pointHighlightStroke: "rgba(151,187,205,1)",
71 | data: [28, 48, 40, 19, 96, 27, 100]
72 | }]
73 | }
74 | },
75 |
76 | polarchart: {
77 | type: 'polar',
78 | data: [{
79 | value: 300,
80 | color: "#F7464A",
81 | highlight: "#FF5A5E",
82 | label: "Red"
83 | }, {
84 | value: 50,
85 | color: "#46BFBD",
86 | highlight: "#5AD3D1",
87 | label: "Green"
88 | }, {
89 | value: 100,
90 | color: "#FDB45C",
91 | highlight: "#FFC870",
92 | label: "Yellow"
93 | }, {
94 | value: 40,
95 | color: "#949FB1",
96 | highlight: "#A8B3C5",
97 | label: "Grey"
98 | }, {
99 | value: 120,
100 | color: "#4D5360",
101 | highlight: "#616774",
102 | label: "Dark Grey"
103 | }]
104 | },
105 |
106 | piechart: {
107 | type: 'pie',
108 | data: [{
109 | value: 300,
110 | color: "#F7464A",
111 | highlight: "#FF5A5E",
112 | label: "Red"
113 | }, {
114 | value: 50,
115 | color: "#46BFBD",
116 | highlight: "#5AD3D1",
117 | label: "Green"
118 | }, {
119 | value: 100,
120 | color: "#FDB45C",
121 | highlight: "#FFC870",
122 | label: "Yellow"
123 | }]
124 | },
125 |
126 | doughnutchart: {
127 | type: 'doughnut',
128 | data: [{
129 | value: 300,
130 | color: "#F7464A",
131 | highlight: "#FF5A5E",
132 | label: "Red"
133 | }, {
134 | value: 50,
135 | color: "#46BFBD",
136 | highlight: "#5AD3D1",
137 | label: "Green"
138 | }, {
139 | value: 100,
140 | color: "#FDB45C",
141 | highlight: "#FFC870",
142 | label: "Yellow"
143 | }]
144 | }
145 | }
--------------------------------------------------------------------------------
/demo/app.js:
--------------------------------------------------------------------------------
1 | import riot from 'riot'
2 | import "../dependencies/js/iframify.js"
3 |
4 | import './demo.tag'
5 | import '../all'
6 |
7 | riot.mount('rg-demo')
--------------------------------------------------------------------------------
/demo/demo.js:
--------------------------------------------------------------------------------
1 | import './_charts.js'
2 |
3 | riot.tag2('rg-demo', '
Alert
Bubble
Hover over me
Code
Chart
Credit Card
Date
{date.date}
Drawer
GA
Google Analytics tag is on this page. Look at Network tab in Developer Tools
iFramify
This is a component. Under 400px, the border of this component will go pink.
This is a component. Under 400px, the border of this component will go pink.
Include
Map
Markdown
Modal
Well hello there!
Pagination
Phone Sim
Placehold.it
Select
Select -w/ filter
Tabs
Tags
Toast
Toggle
Unsplash
>> END
', '', '', function(opts) {
4 | /*
5 | * ALERTS
6 | */
7 | this.alerts = [{
8 | type: 'primary',
9 | text: 'Look! Something you should know about.'
10 | }, {
11 | type: 'secondary',
12 | text: 'Warning! Something sort of bad happened.',
13 | dismissable: false
14 | }, {
15 | type: 'success',
16 | text: 'Success! Well done.'
17 | }, {
18 | type: 'error',
19 | text: 'Error! Something bad happened.',
20 | dismissable: true,
21 | timeout: 2000
22 | }];
23 |
24 | this.addAlert = () => {
25 | this.alerts.push({
26 | type: 'error',
27 | text: 'Eeek! Something broke...'
28 | });
29 | };
30 | /*
31 | * BUBBLE
32 | */
33 |
34 | this.bubble = {
35 | text: 'Ping'
36 | };
37 |
38 | this.updateBubbleText = () => {
39 | this.bubble = {
40 | text: 'Pong!'
41 | };
42 | };
43 | /*
44 | * CHART
45 | */
46 |
47 | Object.assign(this, _charts);
48 | /*
49 | * CODE
50 | */
51 |
52 | this.editorSettings = {
53 | code: 'Hello world!
'
54 | };
55 |
56 | this.changeCode = () => {
57 | this.editorSettings.code = 'this.msg = "Hello RiotGear!";';
58 | this.editorSettings.mode = 'javascript';
59 | };
60 | /*
61 | * CREDIT CARD NUMBER
62 | */
63 |
64 | this.creditcard = {
65 | placeholder: 'Long number on front',
66 | cardnumber: '4000 0000 0000 0002'
67 | };
68 |
69 | this.changeCardNumber = () => {
70 | this.creditcard.cardnumber = 5105105105105100;
71 | };
72 | /*
73 | * DATE
74 | */
75 |
76 | this.date = {
77 | date: moment(),
78 | min: moment().startOf('year'),
79 | max: moment().endOf('year')
80 | };
81 |
82 | this.changeDate = () => {
83 | this.date.date = '2015-01-01';
84 | };
85 | /*
86 | * DRAWER
87 | */
88 |
89 | this.drawer = {
90 | header: 'Drawer',
91 | isvisible: true,
92 | position: 'bottom',
93 | items: [{
94 | text: 'Item 1'
95 | }, {
96 | text: 'Item 2'
97 | }]
98 | };
99 |
100 | this.openDrawer = () => {
101 | this.drawer.isvisible = true;
102 | };
103 | /*
104 | * IFRAMIFY
105 | */
106 |
107 | this.iframify = {};
108 | /*
109 | * INCLUDE
110 | */
111 |
112 | this.include = {
113 | url: 'inc.html'
114 | };
115 | this.includeTwo = {
116 | url: 'inc.html',
117 | unsafe: true
118 | };
119 | this.includeThree = {
120 | url: 'inc2.html',
121 | unsafe: true
122 | /*
123 | * MAP
124 | */
125 |
126 | };
127 | this.on("mount", () => {
128 | this.tags['rg-map'].on('loaded', map => {
129 | var marker = new google.maps.Marker({
130 | position: {
131 | lat: 53.806,
132 | lng: -1.535
133 | },
134 | map: map,
135 | title: 'Hello RiotGear!'
136 | });
137 | });
138 | });
139 | /*
140 | * MARKDOWN
141 | */
142 |
143 | this.markdown = {
144 | content: '**Some** content'
145 | };
146 |
147 | this.changeMarkdown = () => {
148 | this.markdown = {
149 | url: 'inc.md'
150 | };
151 | };
152 | /*
153 | * MODAL
154 | */
155 |
156 | this.modal = {
157 | isvisible: true,
158 | heading: 'Modal heading',
159 | buttons: [{
160 | text: 'Ok',
161 | type: 'primary',
162 | action: () => this.modal.isvisible = false
163 | }, {
164 | text: 'Canel',
165 | action: () => this.modal.isvisible = false
166 | }]
167 | };
168 |
169 | this.toggleModal = () => {
170 | this.modal.isvisible = !this.modal.isvisible;
171 | };
172 |
173 | this.toggleModalType = () => {
174 | this.modal.ghost = !this.modal.ghost;
175 | };
176 |
177 | this.toggleModalDismissable = () => {
178 | this.modal.dismissable = !this.modal.dismissable;
179 | };
180 | /*
181 | * PAGINATION
182 | */
183 |
184 | this.pagination = {
185 | pages: 100,
186 | page: 3,
187 | action: page => console.log(page)
188 | /*
189 | * PHONE SIM
190 | */
191 |
192 | };
193 | this.phonesim = {
194 | url: 'http://riotgear.js.org/'
195 | };
196 |
197 | this.changePhoneSimURL = () => {
198 | this.phonesim.url = 'http://riot.js.org';
199 | };
200 | /*
201 | * PLACEHOLDIT
202 | */
203 |
204 | this.placeholdit = {};
205 |
206 | this.changePlacholdIt = () => {
207 | this.placeholdit.width = 200;
208 | this.placeholdit.height = 100;
209 | this.placeholdit.background = '1fadc5';
210 | this.placeholdit.color = '4df';
211 | this.placeholdit.textsize = 50;
212 | this.placeholdit.text = 'JPEG';
213 | this.placeholdit.format = 'jpg';
214 | };
215 | /*
216 | * SELECT
217 | */
218 |
219 | this.select = {
220 | placeholder: 'Please select a card',
221 | options: [{
222 | id: 0,
223 | text: 'Visa'
224 | }, {
225 | id: 1,
226 | text: 'MasterCard',
227 | selected: true
228 | }, {
229 | id: 2,
230 | text: 'American Express'
231 | }, {
232 | id: 3,
233 | text: 'Discover'
234 | }]
235 | /*
236 | * SELECT WITH FILTER
237 | */
238 |
239 | };
240 | this.selectWithFilter = {
241 | placeholder: 'Please select a card',
242 | filter: 'text',
243 | options: [{
244 | id: 0,
245 | text: 'Visa'
246 | }, {
247 | id: 1,
248 | text: 'MasterCard',
249 | selected: true
250 | }, {
251 | id: 2,
252 | text: 'American Express'
253 | }, {
254 | id: 3,
255 | text: 'Discover'
256 | }]
257 | /*
258 | * UNSPLASH
259 | */
260 |
261 | };
262 | this.unsplash = {};
263 |
264 | this.changeUnsplash = () => {
265 | this.unsplash.width = 200;
266 | this.unsplash.height = 100;
267 | this.unsplash.greyscale = "true";
268 | this.unsplash.random = "true";
269 | this.unsplash.blur = "true";
270 | this.unsplash.image = "491";
271 | this.unsplash.gravity = "north";
272 | };
273 | /*
274 | * TOGGLE
275 | */
276 |
277 | this.toggle = {
278 | type: 'primary',
279 | checked: true
280 | };
281 |
282 | this.changeToggle = () => {
283 | this.toggle.checked = !this.toggle.checked;
284 | };
285 | /*
286 | * TAGS
287 | */
288 |
289 | this.rgTags = {
290 | placeholder: 'Choose a country',
291 | filter: 'text',
292 | options: [{
293 | id: 0,
294 | text: 'England'
295 | }, {
296 | id: 0,
297 | text: 'Scotland'
298 | }, {
299 | id: 0,
300 | text: 'Ireland'
301 | }, {
302 | id: 0,
303 | text: 'Wales'
304 | }],
305 | tags: [{
306 | id: 0,
307 | text: 'Russia'
308 | }]
309 | /*
310 | * TOASTS
311 | */
312 |
313 | };
314 | this.toasts = {
315 | position: 'topright',
316 | toasts: [{
317 | type: 'primary',
318 | text: 'Hey look at me!'
319 | }]
320 | };
321 |
322 | this.changeToasts = () => {
323 | this.toasts.toasts.push({
324 | text: 'Me is a new toast'
325 | });
326 | this.toasts.position = 'bottomleft';
327 | };
328 | /*
329 | * TABS
330 | */
331 |
332 | this.tabs = {
333 | type: 'primary',
334 | tabs: [{
335 | heading: 'Tab one',
336 | text: 'This is tab one'
337 | }, {
338 | heading: 'Tab two',
339 | text: 'This is tab two',
340 | active: true
341 | }, {
342 | heading: 'Disabled tab',
343 | text: 'This is disabled tab',
344 | disabled: true
345 | }, {
346 | heading: 'Tab three',
347 | text: 'This is tab three content',
348 | include: 'tab.html'
349 | }]
350 | };
351 |
352 | this.changeTabContent = () => {
353 | this.tabs.tabs[0].heading = 'take a look at tab three';
354 | this.tabs.tabs[3].include = 'inc.html';
355 | };
356 | });
357 |
--------------------------------------------------------------------------------
/demo/demo.tag:
--------------------------------------------------------------------------------
1 | import './_charts.js'
2 |
3 |
4 | Alert
5 |
6 |
7 |
8 |
9 |
10 |
11 | Bubble
12 |
13 |
14 | Hover over me
15 |
16 |
17 |
18 | Code
19 |
20 |
21 |
22 |
23 |
24 |
25 | Chart
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Credit Card
36 |
37 |
38 |
39 |
40 |
41 |
42 | Date
43 |
44 |
45 |
46 | { date.date }
47 |
48 |
49 |
50 | Drawer
51 |
52 |
53 |
54 |
55 |
56 |
57 | GA
58 |
59 |
60 | Google Analytics tag is on this page. Look at Network tab in Developer Tools
61 |
62 |
63 |
64 | iFramify
65 |
66 |
67 |
This is a component. Under 400px, the border of this component will go pink.
68 |
69 |
70 |
71 |
This is a component. Under 400px, the border of this component will go pink.
72 |
73 |
74 |
75 |
76 | Include
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Map
87 |
88 |
89 |
90 |
91 |
92 | Markdown
93 |
94 |
95 |
96 |
97 |
98 |
99 | Modal
100 |
101 |
102 |
103 | Well hello there!
104 |
105 |
106 |
107 |
108 |
109 |
110 | Pagination
111 |
112 |
113 |
114 |
115 | Phone Sim
116 |
117 |
118 |
119 |
120 |
121 |
122 | Placehold.it
123 |
124 |
125 |
126 |
127 |
128 |
129 | Select
130 |
131 |
132 |
133 |
134 |
135 | Select -w/ filter
136 |
137 |
138 |
139 |
140 |
141 | Tabs
142 |
143 |
144 |
145 |
146 |
147 |
148 | Tags
149 |
150 |
151 |
152 |
153 |
154 | Toast
155 |
156 |
157 |
158 |
159 |
160 |
161 | Toggle
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | Unsplash
171 |
172 |
173 |
174 |
175 |
176 |
177 | >> END
178 |
179 |
531 |
532 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | RiotGear Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/demo/static/img/amex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/amex.png
--------------------------------------------------------------------------------
/demo/static/img/diners_club.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/diners_club.png
--------------------------------------------------------------------------------
/demo/static/img/discover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/discover.png
--------------------------------------------------------------------------------
/demo/static/img/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/example.png
--------------------------------------------------------------------------------
/demo/static/img/first.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/first.jpg
--------------------------------------------------------------------------------
/demo/static/img/jcb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/jcb.png
--------------------------------------------------------------------------------
/demo/static/img/mastercard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/mastercard.png
--------------------------------------------------------------------------------
/demo/static/img/second.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/second.jpg
--------------------------------------------------------------------------------
/demo/static/img/third.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/third.jpg
--------------------------------------------------------------------------------
/demo/static/img/visa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RiotGear/rg/2470502fff96c1dd98804980213ca85499d80d76/demo/static/img/visa.png
--------------------------------------------------------------------------------
/demo/static/inc.html:
--------------------------------------------------------------------------------
1 | This content is in a separate file and injected using the include tag
2 |
--------------------------------------------------------------------------------
/demo/static/inc.md:
--------------------------------------------------------------------------------
1 | *This* content is in a separate file, parsed and injected using the **markdown** tag
2 |
--------------------------------------------------------------------------------
/demo/static/inc2.html:
--------------------------------------------------------------------------------
1 | This is some other content from a different file
2 |
--------------------------------------------------------------------------------
/demo/static/tab.html:
--------------------------------------------------------------------------------
1 | This tab three from a separate file
2 |
--------------------------------------------------------------------------------
/demo/style.css:
--------------------------------------------------------------------------------
1 | .app-container {
2 | padding: 0 100px
3 | }
4 |
5 | h2 {
6 | padding-top: 40px;
7 | }
8 |
9 | .demo {
10 | position: relative;
11 | min-height: 200px;
12 | }
13 |
14 | .no-overflow {
15 | overflow: hidden;
16 | }
17 |
18 | .chart-container {
19 | width: 400px;
20 | }
21 |
22 | button {
23 | border: 0;
24 | border: 1px solid #ccc;
25 | background: #eee;
26 | padding: 5px;
27 | outline: none;
28 | }
29 |
30 | rg-map {
31 | position: absolute;
32 | left: 0;
33 | right: 0;
34 | height: 200px;
35 | }
36 |
37 | .iframify {
38 | width: 400px;
39 | }
40 |
41 | .component {
42 | background-color: #efefef;
43 | border: 1px solid rgba(0, 0, 0, 0.1);
44 | margin: 10px;
45 | padding: 10px;
46 | }
47 |
48 | .component-child {
49 | color: deeppink;
50 | }
51 |
52 | @media (max-width: 400px) {
53 | .component {
54 | border-color: deeppink;
55 | }
56 | }
--------------------------------------------------------------------------------
/dependencies/js/iframify.js:
--------------------------------------------------------------------------------
1 | (function (global) {
2 | var metaViewport = document.querySelector('meta[name="viewport"]');
3 | var metaCharset = document.querySelector('meta[charset]');
4 | var metaViewportStr = metaViewport && metaViewport.outerHTML || '';
5 | var metaCharsetStr = metaCharset && metaCharset.outerHTML || '';
6 | var queryCache = {};
7 |
8 | /**
9 | * Get the styling nodes to inject in the head of the embedded document
10 | *
11 | * @param {String} selector
12 | * @return {String}
13 | */
14 | function getStylingNodes (selector) {
15 | if (typeof queryCache[selector] === 'undefined') {
16 | queryCache[selector] = Array.prototype.map.call(
17 | document.querySelectorAll(selector),
18 | function (stylesheet) {
19 | return stylesheet.outerHTML;
20 | }
21 | ).join('');
22 | }
23 |
24 | return queryCache[selector];
25 | }
26 |
27 | /**
28 | * Get the content for the iframified version of a node.
29 | *
30 | * @param {HTMLElement} node
31 | * @param {Object} options
32 | * @return {String}
33 | */
34 | function getIframeContentForNode (node, options) {
35 | return '' +
36 | '' +
37 | '' +
38 | options.metaCharset +
39 | options.metaViewport +
40 | options.stylesheets +
41 | options.styles +
42 | '' +
43 | '' +
44 | node.innerHTML +
45 | '' +
46 | '';
47 | }
48 |
49 | /**
50 | * Format an object of attributes into a HTML string
51 | *
52 | * @param {Object} attrObj
53 | * @return {String}
54 | */
55 | function formatAttributes (attrObj) {
56 | var attributes = [];
57 |
58 | for (var attribute in attrObj) {
59 | attributes.push(attribute + '="' + attrObj[attribute] + '"');
60 | }
61 |
62 | return attributes.join(' ');
63 | }
64 |
65 | /**
66 | * Get document height (stackoverflow.com/questions/1145850/)
67 | *
68 | * @param {Document} doc
69 | * @return {Number}
70 | */
71 | function getDocumentHeight (doc) {
72 | doc = doc || document;
73 | var body = doc.body;
74 | var html = doc.documentElement;
75 |
76 | return Math.max(
77 | body.scrollHeight, body.offsetHeight,
78 | html.clientHeight, html.scrollHeight, html.offsetHeight
79 | );
80 | }
81 |
82 | function getOptions (options) {
83 | var opts = options || {};
84 | opts.htmlAttr = formatAttributes(opts.htmlAttr || {});
85 | opts.bodyAttr = formatAttributes(opts.bodyAttr || {});
86 | opts.sizingTimeout = opts.sizingTimeout || 500;
87 | opts.styles = (opts.styles ? '' : '');
88 | opts.stylesheets = getStylingNodes(opts.stylesSelector || 'link[rel*=stylesheet], style');
89 | opts.metaCharset = opts.metaCharset || metaCharsetStr;
90 | opts.metaViewport = opts.metaViewport || metaViewportStr;
91 |
92 | return opts;
93 | }
94 |
95 | /**
96 | * Transform a collection of nodes into an iframe version of themselves
97 | * including all the styles they need to perform correctly.
98 | *
99 | * @param {HTMLElement} nodes
100 | * @param {Object} options
101 | * @return undefined
102 | */
103 | function iframify (node, options) {
104 | options = getOptions(options);
105 |
106 | var iframe = document.createElement('iframe');
107 | var html = getIframeContentForNode(node, options);
108 | iframe.srcdoc = html;
109 |
110 | if (!('srcdoc' in iframe)) {
111 | console.log(
112 | 'Your browser does not support the `srcdoc` attribute on elements.' +
113 | 'Therefore, it is not possible to wrap this node with an iframe due' +
114 | 'to CORS policy.'
115 | );
116 |
117 | return null;
118 | }
119 |
120 | node.parentNode.replaceChild(iframe, node);
121 |
122 | setTimeout(function () {
123 | var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
124 | iframe.height = getDocumentHeight(iframeDocument);
125 | }, options.sizingTimeout);
126 |
127 | return iframe;
128 | }
129 |
130 | global.iframify = iframify;
131 | }(window));
132 |
--------------------------------------------------------------------------------
/dist/rg-alerts/rg-alerts.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-alerts', '', '', '', function(opts) {
2 | this.on("mount", () => this.update());
3 | this.on('update', () => {
4 | if (!opts.alerts) return;
5 | opts.alerts.forEach(alert => {
6 | if (typeof alert.isvisible === 'undefined') alert.isvisible = true;
7 |
8 | if (alert.timeout) {
9 | alert.startTimer = () => {
10 | alert.timer = setTimeout(() => {
11 | this.dismiss({
12 | item: alert
13 | });
14 | }, alert.timeout);
15 | };
16 |
17 | alert.startTimer();
18 | }
19 | });
20 | });
21 |
22 | this.dismiss = e => {
23 | const alert = e.item;
24 | alert.isvisible = false;
25 | clearTimeout(alert.timer);
26 | this.trigger('dismiss', alert);
27 | this.update();
28 | };
29 |
30 | this.select = e => {
31 | const alert = e.item;
32 | if (alert.onclick) alert.onclick(alert);
33 | this.trigger('select', alert);
34 | };
35 | });
36 |
--------------------------------------------------------------------------------
/dist/rg-bubble/rg-bubble.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-bubble', '', 'rg-bubble .context,[data-is="rg-bubble"] .context,rg-bubble .content,[data-is="rg-bubble"] .content{ display: inline-block; position: relative; } rg-bubble .bubble,[data-is="rg-bubble"] .bubble{ position: absolute; top: -70px; left: 50%; transform: translate3d(-50%, 0, 0); }', '', function(opts) {
2 | this.showBubble = () => {
3 | clearTimeout(this._timer);
4 | this.isvisible = true;
5 | };
6 |
7 | this.hideBubble = () => {
8 | this._timer = setTimeout(() => {
9 | this.isvisible = false;
10 | this.update();
11 | }, 1000);
12 | };
13 |
14 | this.toggleBubble = () => {
15 | this.isvisible = !this.isvisible;
16 | };
17 | });
18 |
--------------------------------------------------------------------------------
/dist/rg-chart/rg-chart.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-chart', '', 'rg-chart,[data-is="rg-chart"]{ display: inline-block; width: 100%; }', '', function(opts) {
2 | Chart.defaults.global.responsive = true;
3 | this.on('mount', () => {
4 | drawChart();
5 | });
6 | this.on('loaded', c => {
7 | this.on('unmount', () => {
8 | c.destroy();
9 | });
10 | });
11 |
12 | const drawChart = () => {
13 | if (!opts.chart) return;
14 | let ctx = this.root.querySelector('canvas').getContext('2d');
15 | let chart = new Chart(ctx);
16 | let c = null;
17 |
18 | switch (opts.chart.type) {
19 | case 'line':
20 | c = chart.Line(opts.chart.data, opts.chart.options);
21 | break;
22 |
23 | case 'radar':
24 | c = chart.Radar(opts.chart.data, opts.chart.options);
25 | break;
26 |
27 | case 'polar':
28 | c = chart.PolarArea(opts.chart.data, opts.chart.options);
29 | break;
30 |
31 | case 'pie':
32 | c = chart.Pie(opts.chart.data, opts.chart.options);
33 | break;
34 |
35 | case 'doughnut':
36 | c = chart.Doughnut(opts.chart.data, opts.chart.options);
37 | break;
38 |
39 | default:
40 | c = chart.Bar(opts.chart.data, opts.chart.options);
41 | break;
42 | }
43 |
44 | this.trigger('loaded', c);
45 | };
46 | });
47 |
--------------------------------------------------------------------------------
/dist/rg-code/rg-code.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-code', '', 'rg-code .editor,[data-is="rg-code"] .editor{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; }', '', function(opts) {
2 | if (!opts.editor) opts.editor = {
3 | code: ''
4 | };
5 | let editor;
6 |
7 | const setupEditor = () => {
8 | editor.setTheme(`ace/theme/${opts.editor.theme || 'monokai'}`);
9 | editor.getSession().setMode(`ace/mode/${opts.editor.mode || 'html'}`);
10 | editor.getSession().setTabSize(opts.editor.tabsize || 2);
11 | editor.getSession().setUseSoftTabs(opts.editor.softtabs);
12 | editor.getSession().setUseWrapMode(opts.editor.wordwrap);
13 | editor.setReadOnly(opts.editor.readonly);
14 | };
15 |
16 | this.on('update', () => {
17 | /* istanbul ignore next */
18 | if (!this.isMounted) {
19 | return;
20 | } // riot2 compatibility
21 |
22 | setupEditor();
23 | if (opts.editor.code != editor.getValue()) editor.setValue(opts.editor.code, 1);
24 | });
25 | this.on('mount', () => {
26 | opts.editor.code = opts.editor.code || "";
27 | this.editor = editor = ace.edit(this.root.querySelector('.editor'));
28 | editor.$blockScrolling = Infinity;
29 |
30 | if (opts.editor.url) {
31 | const req = new XMLHttpRequest();
32 |
33 | req.onload = resp => {
34 | opts.editor.code = resp;
35 | this.update();
36 | };
37 |
38 | req.open('get', opts.editor.url, true);
39 | req.send();
40 | }
41 |
42 | editor.setValue(opts.editor.code, 1);
43 | /* istanbul ignore next */
44 |
45 | editor.getSession().on('change', e => {
46 | opts.editor.code = editor.getValue();
47 | this.trigger('onchange', editor.getValue());
48 | });
49 | this.update();
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/dist/rg-credit-card/rg-credit-card-number.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-credit-card-number', '', 'rg-credit-card-number .card-no,[data-is="rg-credit-card-number"] .card-no{ padding-right: 60px; background-repeat: no-repeat; background-position: right center; background-size: 60px; } rg-credit-card-number .amex,[data-is="rg-credit-card-number"] .amex{ background-image: url(img/amex.png); } rg-credit-card-number .diners_club,[data-is="rg-credit-card-number"] .diners_club{ background-image: url(img/diners_club.png); } rg-credit-card-number .discover,[data-is="rg-credit-card-number"] .discover{ background-image: url(img/discover.png); } rg-credit-card-number .jcb,[data-is="rg-credit-card-number"] .jcb{ background-image: url(img/jcb.png); } rg-credit-card-number .mastercard,[data-is="rg-credit-card-number"] .mastercard{ background-image: url(img/mastercard.png); } rg-credit-card-number .visa,[data-is="rg-credit-card-number"] .visa{ background-image: url(img/visa.png); }', '', function(opts) {
2 | this.on("mount", () => {
3 | this.input = this.root.querySelector("input");
4 | this.input.value = opts.card.cardnumber;
5 | this.update();
6 | }); // this just triggers update
7 |
8 | this.oninput = () => {};
9 |
10 | if (!opts.card) opts.card = {
11 | cardnumber: ''
12 | };
13 | this.on("update", () => {
14 | /* istanbul ignore next */
15 | if (!this.isMounted) {
16 | return;
17 | } // riot2 compatibility
18 |
19 | opts.card.cardnumber = this.input.value;
20 | const res = validateCreditCard(opts.card.cardnumber);
21 | opts.card.valid = res.valid;
22 | this.icon = opts.card.valid ? res.card_type.name : '';
23 | });
24 |
25 | function validateCreditCard(input) {
26 | var card, card_type, card_types, get_card_type, is_valid_length, is_valid_luhn, normalize, validate, validate_number, _i, _len;
27 |
28 | card_types = [{
29 | name: 'amex',
30 | icon: 'images/amex.png',
31 | pattern: /^3[47]/,
32 | valid_length: [15]
33 | }, {
34 | name: 'diners_club',
35 | icon: 'images/diners_club.png',
36 | pattern: /^30[0-5]/,
37 | valid_length: [14]
38 | }, {
39 | name: 'diners_club',
40 | icon: 'images/diners_club.png',
41 | pattern: /^36/,
42 | valid_length: [14]
43 | }, {
44 | name: 'jcb',
45 | icon: 'images/jcb.png',
46 | pattern: /^35(2[89]|[3-8][0-9])/,
47 | valid_length: [16]
48 | }, {
49 | name: 'laser',
50 | pattern: /^(6304|670[69]|6771)/,
51 | valid_length: [16, 17, 18, 19]
52 | }, {
53 | name: 'visa_electron',
54 | pattern: /^(4026|417500|4508|4844|491(3|7))/,
55 | valid_length: [16]
56 | }, {
57 | name: 'visa',
58 | icon: 'images/visa.png',
59 | pattern: /^4/,
60 | valid_length: [16]
61 | }, {
62 | name: 'mastercard',
63 | icon: 'images/mastercard.png',
64 | pattern: /^5[1-5]/,
65 | valid_length: [16]
66 | }, {
67 | name: 'maestro',
68 | pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
69 | valid_length: [12, 13, 14, 15, 16, 17, 18, 19]
70 | }, {
71 | name: 'discover',
72 | icon: 'images/discover.png',
73 | pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
74 | valid_length: [16]
75 | }];
76 | var options = {
77 | accept: card_types.map(c => c.name)
78 | };
79 |
80 | get_card_type = function (number) {
81 | return card_types.find(c => number.match(c.pattern)) || null;
82 | };
83 |
84 | is_valid_luhn = function (number) {
85 | var digit, n, sum, _j, _len1, _ref1;
86 |
87 | sum = 0;
88 | _ref1 = number.split('').reverse();
89 |
90 | for (n = _j = 0, _len1 = _ref1.length; _j < _len1; n = ++_j) {
91 | digit = _ref1[n];
92 | digit = +digit;
93 |
94 | if (n % 2) {
95 | digit *= 2;
96 |
97 | if (digit < 10) {
98 | sum += digit;
99 | } else {
100 | sum += digit - 9;
101 | }
102 | } else {
103 | sum += digit;
104 | }
105 | }
106 |
107 | return sum % 10 === 0;
108 | };
109 |
110 | is_valid_length = function (number, card_type) {
111 | return card_type.valid_length.indexOf(number.length) !== -1;
112 | };
113 |
114 | validate_number = function (_this) {
115 | return function (number) {
116 | var length_valid, luhn_valid;
117 | card_type = get_card_type(number);
118 | luhn_valid = false;
119 | length_valid = false;
120 |
121 | if (card_type != null) {
122 | luhn_valid = is_valid_luhn(number);
123 | length_valid = is_valid_length(number, card_type);
124 | }
125 |
126 | return {
127 | card_type: card_type,
128 | valid: luhn_valid && length_valid,
129 | luhn_valid: luhn_valid,
130 | length_valid: length_valid
131 | };
132 | };
133 | }(this);
134 |
135 | normalize = function (number) {
136 | return number.replace(/[ -]/g, '');
137 | };
138 |
139 | validate = function (_this) {
140 | return function () {
141 | return validate_number(normalize(input));
142 | };
143 | }(this);
144 |
145 | return validate(input);
146 | }
147 | });
148 |
--------------------------------------------------------------------------------
/dist/rg-date/rg-date.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-date', ' Mo
Tu
We
Th
Fr
Sa
Su
', 'rg-date .container,[data-is="rg-date"] .container{ position: relative; display: inline-block; cursor: pointer; } rg-date .calendar,[data-is="rg-date"] .calendar{ position: absolute; min-width: 300px; margin-top: .5em; left: 0; }', '', function(opts) {
2 | const toMoment = d => {
3 | if (!moment.isMoment(d)) d = moment(d);
4 | if (d.isValid()) return d;
5 | return moment();
6 | };
7 |
8 | const handleClickOutside = e => {
9 | if (!this.root.contains(e.target)) this.close();
10 | this.update();
11 | };
12 |
13 | this.dayObj = dayDate => {
14 | const dateObj = dayDate || moment();
15 | return {
16 | date: dateObj,
17 | selected: opts.date.date.isSame(dayDate, 'day'),
18 | today: moment().isSame(dayDate, 'day'),
19 | disabled: opts.date.min && opts.date.min.isAfter(dayDate) || opts.date.max && opts.date.max.isBefore(dayDate)
20 | };
21 | };
22 |
23 | const buildCalendar = () => {
24 | this.format = 'LL';
25 | this.yearFormat = 'YYYY';
26 | this.monthFormat = 'MMMM';
27 | this.dayFormat = 'DD';
28 | this.days = [];
29 | this.startBuffer = [];
30 | this.endBuffer = [];
31 | const begin = moment(opts.date.date).startOf('month');
32 | const daysInMonth = moment(opts.date.date).daysInMonth();
33 | const end = moment(opts.date.date).endOf('month');
34 |
35 | for (let i = begin.isoWeekday() - 1; i > 0; i -= 1) {
36 | const d = moment(begin).subtract(i, 'days');
37 | this.startBuffer.push(this.dayObj(d));
38 | }
39 |
40 | for (let i = 0; i < daysInMonth; i++) {
41 | const current = moment(begin).add(i, 'days');
42 | this.days.push(this.dayObj(current));
43 | }
44 |
45 | for (let i = end.isoWeekday() + 1; i <= 7; i++) {
46 | const d = moment(end).add(i - end.isoWeekday(), 'days');
47 | this.endBuffer.push(this.dayObj(d));
48 | }
49 | };
50 |
51 | this.on('mount', () => {
52 | if (!opts.date) opts.date = {
53 | date: moment()
54 | };
55 | if (!opts.date.date) opts.date.date = moment();
56 | opts.date.date = toMoment(opts.date.date);
57 | opts.date.min = toMoment(opts.date.min || -8.64e15);
58 |
59 | if (opts.date.min.isAfter(opts.date.date, 'day')) {
60 | opts.date.date = moment(opts.date.min);
61 | }
62 |
63 | opts.date.max = toMoment(opts.date.max || 8.64e15);
64 |
65 | if (opts.date.max.isBefore(opts.date.date, 'day')) {
66 | opts.date.date = moment(opts.date.max);
67 | }
68 |
69 | document.addEventListener('click', handleClickOutside);
70 | this.update();
71 | });
72 | this.on('update', () => {
73 | /* istanbul ignore next */
74 | if (!this.isMounted) {
75 | return;
76 | } // riot2 compatibility
77 |
78 | opts.date.date = toMoment(opts.date.date);
79 | buildCalendar();
80 | this.value = opts.date.date.format(this.format);
81 | });
82 | this.on('unmount', () => {
83 | document.removeEventListener('click', handleClickOutside);
84 | });
85 |
86 | this.open = () => {
87 | this.isvisible = true;
88 | this.trigger('open');
89 | };
90 |
91 | this.close = () => {
92 | if (this.isvisible) {
93 | this.isvisible = false;
94 | this.trigger('close');
95 | }
96 | };
97 |
98 | this.select = e => {
99 | opts.date.date = e.item.day.date;
100 | this.trigger('select', opts.date.date);
101 | };
102 |
103 | this.setToday = () => {
104 | opts.date.date = moment();
105 | this.trigger('select', opts.date.date);
106 | };
107 |
108 | this.prevYear = () => {
109 | opts.date.date = opts.date.date.subtract(1, 'year');
110 | };
111 |
112 | this.nextYear = () => {
113 | opts.date.date = opts.date.date.add(1, 'year');
114 | };
115 |
116 | this.prevMonth = () => {
117 | opts.date.date = opts.date.date.subtract(1, 'month');
118 | };
119 |
120 | this.nextMonth = () => {
121 | opts.date.date = opts.date.date.add(1, 'month');
122 | };
123 | });
124 |
--------------------------------------------------------------------------------
/dist/rg-drawer/rg-drawer.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-drawer', ' ', '', '', function(opts) {
2 | if (!opts.drawer) opts.drawer = {};
3 |
4 | this.close = () => {
5 | opts.drawer.isvisible = false;
6 | this.trigger('close');
7 | };
8 |
9 | this.select = e => {
10 | opts.drawer.items.forEach(item => item.active = false);
11 | e.item.active = true;
12 | this.trigger('select', e.item);
13 | };
14 | });
15 |
--------------------------------------------------------------------------------
/dist/rg-ga/rg-ga.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-ga', '', '', '', function(opts) {
2 | /* istanbul ignore next */
3 | (function (i, s, o, g, r, a, m) {
4 | i['GoogleAnalyticsObject'] = r;
5 | i[r] = i[r] || function () {
6 | (i[r].q = i[r].q || []).push(arguments);
7 | }, i[r].l = 1 * new Date();
8 | a = s.createElement(o), m = s.getElementsByTagName(o)[0];
9 | a.async = 1;
10 | a.src = g;
11 | m.parentNode.insertBefore(a, m);
12 | })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
13 |
14 | ga('create', opts.property, 'auto');
15 | ga('send', 'pageview');
16 | });
17 |
--------------------------------------------------------------------------------
/dist/rg-iframify/rg-iframify.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-iframify', '', 'rg-iframify .iframify,[data-is="rg-iframify"] .iframify{ margin: 0; padding: 0; } rg-iframify iframe,[data-is="rg-iframify"] iframe{ position: relative; width: 100%; border: 0; }', '', function(opts) {
2 | this.on('mount', () => {
3 | iframify(this.root.querySelector('.frame'), this.opts);
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/dist/rg-include/rg-include.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-include', ' {responseText}
', '', '', function(opts) {
2 | const fetch = () => {
3 | const req = new XMLHttpRequest();
4 |
5 | req.onload = resp => {
6 | if (opts.include.unsafe) this.root.innerHTML = req.responseText;else this.responseText = req.responseText;
7 | this.update();
8 | this.trigger('loaded');
9 | };
10 |
11 | req.open('get', opts.include.url, true);
12 | req.send();
13 | this.trigger('loading');
14 | };
15 |
16 | this.on('mount', () => {
17 | fetch();
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/dist/rg-map/rg-map.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-map', '', 'rg-map .rg-map,[data-is="rg-map"] .rg-map{ margin: 0; padding: 0; width: 100%; height: 100%; } rg-map .rg-map img,[data-is="rg-map"] .rg-map img{ max-width: inherit; }', '', function(opts) {
2 | window.rg = window.rg || {};
3 | window.rg.gmap = riot.observable({
4 | initialize: () => {
5 | window.rg.gmap.trigger('initialize');
6 | }
7 | });
8 | this.on('mount', () => {
9 | if (!opts.map) opts.map = {
10 | center: {
11 | lat: 53.806,
12 | lng: -1.535
13 | },
14 | zoom: 7
15 | /* istanbul ignore next */
16 |
17 | };
18 | rg.gmap.on('initialize', () => {
19 | opts.map.mapObj = new google.maps.Map(this.root.querySelector('.rg-map'), opts.map);
20 | this.trigger('loaded', opts.map.mapObj);
21 | });
22 |
23 | if (!document.getElementById('gmap_script')) {
24 | let script = document.createElement('script');
25 | script.setAttribute('id', 'gmap_script');
26 | script.type = 'text/javascript';
27 | script.src = 'https://maps.googleapis.com/maps/api/js?callback=window.rg.gmap.initialize';
28 | document.body.appendChild(script);
29 | }
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/dist/rg-markdown/rg-markdown.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-markdown', '', '', '', function(opts) {
2 | this.on("mount", () => this.update());
3 | this.reader = new commonmark.Parser();
4 | this.writer = new commonmark.HtmlRenderer();
5 | this.on('update', () => {
6 | if (!opts.markdown) opts.markdown = {};
7 |
8 | if (opts.markdown.content) {
9 | this.root.innerHTML = this.writer.render(this.reader.parse(opts.markdown.content));
10 | } else if (opts.markdown.url) {
11 | const req = new XMLHttpRequest();
12 |
13 | req.onload = resp => {
14 | this.root.innerHTML = this.writer.render(this.reader.parse(req.responseText));
15 | this.trigger('loaded');
16 | };
17 |
18 | req.open('get', opts.markdown.url, true);
19 | req.send();
20 | this.trigger('loading');
21 | }
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/dist/rg-modal/rg-modal.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-modal', ' ', 'rg-modal .modal--ghost .modal__footer .button,[data-is="rg-modal"] .modal--ghost .modal__footer .button{ margin: 0 .5em 0 0; }', '', function(opts) {
2 | if (!opts.modal) opts.modal = {};
3 |
4 | this.close = () => {
5 | if (opts.modal.dismissable) {
6 | opts.modal.isvisible = false;
7 | this.trigger('close');
8 | }
9 | };
10 | });
11 |
--------------------------------------------------------------------------------
/dist/rg-pagination/rg-pagination.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-pagination', '', '', '', function(opts) {
2 | if (!opts.pagination) opts.pagination = {
3 | pages: 1,
4 | page: 1
5 | };
6 | this.on('page', () => {
7 | const btns = this.root.querySelectorAll('button');
8 |
9 | for (let i = 0; i < btns.length; i++) {
10 | btns[i].blur();
11 | }
12 | });
13 |
14 | this.forward = () => {
15 | opts.pagination.page++;
16 | this.trigger('page', opts.pagination.page);
17 | };
18 |
19 | this.back = () => {
20 | opts.pagination.page--;
21 | this.trigger('page', opts.pagination.page);
22 | };
23 |
24 | this.first = () => {
25 | opts.pagination.page = 1;
26 | this.trigger('page', opts.pagination.page);
27 | };
28 |
29 | this.last = () => {
30 | opts.pagination.page = opts.pagination.pages;
31 | this.trigger('page', opts.pagination.page);
32 | };
33 | });
34 |
--------------------------------------------------------------------------------
/dist/rg-phone-sim/rg-phone-sim.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-phone-sim', '
', 'rg-phone-sim .emulator,[data-is="rg-phone-sim"] .emulator{ position: relative; width: 365px; height: 792px; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW0AAAMYCAMAAAA3r0ZLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwBQTFRFMDk6+vr6KTM0lJucMz4/PklKJS8wLTg5Qk1OxsjILzo7gomJ2NvbdH5/ho2O9fb2KzY3ztHRPEdIOkVGZWxtjJSVOEJDkpeYWGRluL2+KTQ1vcHBoaWlPUZHcnp6nKKjOkRF1NfXqa2tp62tZnBxanV2VmFiZ29wVl1eaXJzbXR04uTktbq7QElK1tnZipKTi5CRTlZXpKioo6mqXmlqUVlaOEFCSVFSUFxdISssT1tcTlpbJC4vIiwtTVlaJjAxIy0uTFhZS1dYJzEyKDIzSlZXPUhJOURFO0ZHSVVWKzU2P0pLKjQ1OENEND0+QEtMLDY3SFRVN0JDQ05PLTc4ND9ANUBBQUxNNkFCR1NUMTo7RE9QLjg5N0BBR1JTRlJTLzk6RVFSMjs8RVBRRlFSNj9AMzw9SFNUMj0+IissMTs8MDo7SVRVRFBRMDs8MTw9IiwsMz0+Mjw9SlVWQ09QLjk6NT4/S1ZXND4/JC4uQU1OIy0tQk5PTFdYTVhZQExNTllaJS8vJzIyP0tMLzg5LDc4KDMzNT9AKjU1N0FCNkBBJjAwIywtMDs7Mj09NkFBJjExLjk5LDc3N0JCNUBAKjU2MTw8LDU2Ljc4OUNEKDEyQU1NPEhIPEhJO0dHOkZGND8/Qk5ORFBQQ09PLTY3OUREPkpKPkpLPUlJT1pbP0tLJTAwPUlKJzAxKjM07u/vKTIzsbW2YGprtLm50tXWPkhJo6endn+A3d/f6uvreoOEg4yN2tvc/Pz8n6am8/T0VFtcm6CgJS4v4OLi5ufnYGdncnt8dHp7gYaHJC0uu8DAjJGRQkxNxMfHKzQ1YGtsS1NUaXN0bnh5yMzMyszMy83Oy8/PdoCAKDIy7O3tT1dYuLu70NTUbXd46Onq6erreoCA2dzc8PHx8vPz5OXlnaSkn6Wmqq6ucHZ2t7y8o6eoeoSEkJaWm5+gW2ZnZG5vqa+wOEFB09bWtru7qrCwcXd4t7u83eDgzM7O7/DwNT4+7e7uwMPDwcPEeH5/////70wnUQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAA+NSURBVHja7N13nBTlGcDxEQI5AmJQBAkcnqhEDIhoWMt5iogmQbOaYNrqYrJh16gplmTVkILJpYCmF+DSE1JIcjRR7L333ntPYjQxvTl55tnr7N7t7uw+vDP3+/0x3G3hs5+vr++8M7s7eH75Xb5x+rOjN017aeq+tO++U1+atmn0s9M3Xl6BoFfm466ZOPROhIt259CJ19RS++7LdgW133a97O7aaI/a+VE0y+jRnUeF1p6wqfvvaz6+YVjT0jMyJ3rkeSdmzljaNKzh+OZuoE0TQmmvv67zLzrwmMY8wkXLNx5zYCfTdeur1p6wdeegblgKar8tbegc4lv/rirtjTMLT99/UVMKzgFLNS3avwA2c2Pl2n8tPHV1QxLJMks2rC6g/alC7ScvKozrhhyIFZRrKIzvi56sRHt94b/RIsZ1xeN7UYFuffna4/UJB68Er4rGHax648vUfmqkPnxBBrmqyixQv5FPlaP9Dz2eWdIEW9U1LdFjnQsG1n5ETz4dyowdavY+VE9XPTKQ9phddPfICjvk6lt3lruM6V97j132l26BK3S3BJAv79Gf9jN3BY85HKsadHhAedebSmtf+ofgEcOQqknDAsyLLi2pPTq4/0icatSRAefoUto7Bvc2oFSzGgLQHYtr3xTct5DVSA1XJgsD0puKaa99s9wzlwPImh5WzhXTl/5TRHt7uaN5GUI1bVmzqL64ufZfgkF/GD417rCA9e99tf8VzCPHoVPzjhPXaVv10d5bblzCyZE6nDIJ5pKde2u/Egz487Cp1zHlHr20h8otp50ETT2WgaeL7dCe2vcF/uOQqUsrA9z7emgHQ3thdEZLLpeL0kHYwq7BrdqjAv2ofEAnlU0EZaPjvTTgHdWlvXeEhnYu0VkuUoN7707tbW6X35oiciyc6C4yZxmaxPf2bTq0z5VfTo/IC8/20M5GZnAHy5JzO7Tvj85bCKlEzyIzdQdvLNxf0L4wmMQjMgnmemlHZubOBcQXqvb0CO0jk720o3OmIdhPTlft4FTrth5ju55tK8bbq/YG+emUiLzqTC/t6Lz1cYoYbwi0r47QisTz0j2w0xE6ngxWJVeLdrD+WxCZVx3J9ba0QNeAnj9T/twuOi87GcF9pLSdKM8U7Q2rV6+O0jcQMoXJJB2t96tzorzB99Y2NzfPjdQL9zLJZDJynw2YK85rvZ1ku9Cjuq+4xXknb4Js+XxU/WsQ5wnec7LlDcn6d544P+ddLFu+zlT/Vorzxd5k2fIJqfq3TJwney/Lls+RGBwniPPL3g6y5aOWBstWcd7BmypbLjhS/1LiPNWTTTMWBik02mijTWijTWijjTbFVTuZTqSTRW8OUzqJdpGyxT89mU2ELYv25kO4+LvnyUT4kmj3LV38YzjpGmin3dReIm2pF9BlU+LmMDmnrdBbUntQje0trj2o5m2FPlBiTWKQQm9R7cG03nZAexCFNtpoE9poE9poo01oo01oo01oo4021VT7MxIUBik02mijTeG1D5agMEih0UYbbUIbbUIbbbQJbbQJbbQJbbTRplppf1qCwiCFRhtttCm89lwJCoMUGm200Sa00Sa00Uab0Eab0Eab0EY73tqnS1AYpNBoo402hdc+VILCIIVGG220CW20CW200Sa00Sa00aYC9GkSFAYpNNpoo01oR0v7bRIUBik02mijTWijTWijjTahjTah7bL2hyUoDFJotNFGm9BGm0ppv0OCwiCFRhtttAlttAlttNEmtOOhfbwEhUEKjTbaaBPaaBPaLmi/T4LCIIVGG220CW20CW200ab6aS+UoDBIodFGG21CG21C2wXt4yQoDFJotNFGm9BGm9BGe7BpL5KgMEih0UYbbUIbbULbBe0PSFAYpNBoo402oY02oY32YNP+oASFQQqNNtpoE9poE9poDzbtj0hQGKTQaKONNqGNNpXS/qkEhUEKfYwEhUEKjTbaaBPaaBPaaA827Y9LUBik0GijjTahHS3tn0lQGKTQCyQoDFJotNFGm9BGm9BGG22qn/anJCgMUmi00Uabwmv/RILCIIVukKAwSKHRRhttQhttQhtttKl+2p+UoDBIodFGG20Kr/09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\'); background-repeat: no-repeat; background-position: center; background-size: cover; } rg-phone-sim .screen,[data-is="rg-phone-sim"] .screen{ position: absolute; top: 105px; left: 22px; background-color: white; width: 320px; height: 568px; border: 0; }', '', function(opts) {
2 | });
3 |
--------------------------------------------------------------------------------
/dist/rg-placeholdit/rg-placeholdit.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-placeholdit', '
', '', '', function(opts) {
2 | if (!opts.placeholdit) opts.placeholdit = {};
3 | this.on("mount", () => this.update());
4 | this.on('update', () => {
5 | opts.placeholdit.width = opts.placeholdit.width || 450;
6 | opts.placeholdit.height = opts.placeholdit.height || 250;
7 | opts.placeholdit.background = opts.placeholdit.background || '000';
8 | opts.placeholdit.color = opts.placeholdit.color || 'fff';
9 | opts.placeholdit.text = opts.placeholdit.text || `${opts.placeholdit.width} x ${opts.placeholdit.height}`;
10 | opts.placeholdit.textsize = opts.placeholdit.textsize || 30;
11 | opts.placeholdit.format = opts.placeholdit.format || 'png';
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/dist/rg-raw/rg-raw.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-raw', '', '', '', function(opts) {
2 | this.on('mount', () => this.update());
3 | this.on('update', () => {
4 | this.root.innerHTML = opts.content || '';
5 | });
6 | });
7 |
--------------------------------------------------------------------------------
/dist/rg-select/rg-select.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-select', ' ', 'rg-select .menu,[data-is="rg-select"] .menu{ position: absolute; }', '', function(opts) {
2 | /* istanbul ignore next */
3 | if (!opts.select) opts.select = {
4 | options: []
5 | };
6 |
7 | const handleClickOutside = e => {
8 | if (!this.root.contains(e.target)) this.close();
9 | this.update();
10 | };
11 |
12 | this.on('mount', () => {
13 | document.addEventListener('click', handleClickOutside);
14 | this.update();
15 | });
16 | this.on('unmount', () => {
17 | document.removeEventListener('click', handleClickOutside);
18 | });
19 |
20 | this.keydown = e => {
21 | const was_open = this.isvisible;
22 | this.open();
23 |
24 | if (e.keyCode === 38) {
25 | // ArrowUp
26 | this.navigate(-1);
27 | e.preventDefault();
28 | } else if (e.keyCode === 40) {
29 | // ArrowDown
30 | this.navigate(1);
31 | e.preventDefault();
32 | } else if (e.keyCode === 13) {
33 | // enter
34 | if (!was_open) {
35 | // if enter is pressed and wasn't opened, just open (above) and leave
36 | return;
37 | }
38 |
39 | const item = getActiveItem() || this.options[0];
40 | item && this.select({
41 | item
42 | });
43 | this.close();
44 | e.preventDefault();
45 | } else {
46 | this._navigate(0);
47 | }
48 | };
49 |
50 | this.select = e => {
51 | const value = e.item.text;
52 | getInput().value = e.item.text;
53 | this.trigger('select', e.item.text);
54 | opts.onselect && opts.onselect(e.item, this);
55 | opts.select.options.forEach(o => o.selected = false);
56 | e.item.selected = true;
57 | this.close();
58 | };
59 |
60 | this.navigate = dir => {
61 | const {
62 | options
63 | } = this;
64 | let new_index = (options.findIndex(o => o.active) + dir) % options.length; // javascript doesn't mod properly :(
65 |
66 | if (new_index < 0) {
67 | new_index = options.length - 1;
68 | }
69 |
70 | this._navigate(new_index);
71 | };
72 |
73 | this._navigate = index => {
74 | opts.select.options.forEach(o => o.active = false);
75 | const item = this.options[index || 0];
76 |
77 | if (item) {
78 | item.active = true;
79 | }
80 | };
81 |
82 | this.on('update', () => {
83 | /* istanbul ignore next */
84 | if (!this.isMounted) {
85 | return;
86 | } // riot2 compatibility
87 |
88 | const value = getValue();
89 | this.options = opts.select.options;
90 |
91 | if (opts.select.filter) {
92 | if (value) {
93 | const r = new RegExp(value, 'i');
94 | this.options = this.options.filter(o => o.text.match(r));
95 | this.trigger('filter');
96 | }
97 | }
98 | });
99 |
100 | const getValue = () => getInput().value;
101 |
102 | const getInput = () => this.root.querySelector('input');
103 |
104 | const getActiveItem = () => {
105 | return this.options.find(o => o.active);
106 | };
107 |
108 | this.open = e => {
109 | this.isvisible = true;
110 | this.trigger('open');
111 | };
112 |
113 | this.close = e => {
114 | this.isvisible = false;
115 | this.trigger('close');
116 | };
117 | });
118 |
--------------------------------------------------------------------------------
/dist/rg-tabs/rg-tabs.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-tabs', ' {text}
{include.responseText}
', '', '', function(opts) {
2 | if (!opts.tabs) opts.tabs = {};
3 | this.on('mount', () => this.update());
4 |
5 | const fetch = tab => {
6 | if (tab.raw) {
7 | return;
8 | }
9 |
10 | const req = new XMLHttpRequest();
11 |
12 | req.onload = resp => {
13 | tab.raw = req.responseText;
14 | tab.text = undefined;
15 | this.update();
16 | this.trigger('loaded', tab);
17 | };
18 |
19 | req.open('get', tab.include, true);
20 | req.send();
21 | this.trigger('loading', tab);
22 | };
23 |
24 | this.open = e => {
25 | let tab = e.item;
26 |
27 | if (!tab.disabled && !tab.active) {
28 | opts.tabs.tabs.forEach(tab => {
29 | tab.active = false;
30 | });
31 | this.trigger('open', tab);
32 | tab.active = true;
33 | }
34 | };
35 |
36 | this.on('update', () => {
37 | if (!Array.isArray(opts.tabs.tabs)) return;
38 | opts.tabs.tabs.forEach(tab => {
39 | if (!tab.disabled && tab.active && tab.include) {
40 | fetch(tab);
41 | }
42 | });
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/dist/rg-tags/rg-tags.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-tags', '
', 'rg-tags .menu,[data-is="rg-tags"] .menu{ position: absolute; }', '', function(opts) {
2 | this.on('mount', () => this.update());
3 | if (!opts.tags) opts.tags = {
4 | options: [],
5 | tags: []
6 | };
7 | if (!opts.tags.options) opts.tags.options = []; // options for rg-select
8 |
9 | if (!opts.tags.tags) opts.tags.tags = [];
10 | this.select_opts = Object.assign({
11 | filter: true
12 | }, opts.tags);
13 |
14 | this.select = (item, tag) => {
15 | this.addTag(item);
16 | this.trigger('select', item);
17 | this.root.querySelector('input').value = '';
18 | this.update();
19 | };
20 |
21 | this.addTag = item => {
22 | if (opts.tags.tags.indexOf(item) == -1) {
23 | opts.tags.tags.push(item);
24 | }
25 | };
26 |
27 | this.removeTag = e => {
28 | opts.tags.tags = opts.tags.tags.filter(tag => {
29 | if (tag._id != e.item._id) return tag;
30 | });
31 | };
32 |
33 | this.on('update', () => {
34 | opts.tags.options.forEach(item => {
35 | item._id = item._id || (Math.floor(Math.random() * 60466175) + 1679615).toString(36);
36 | });
37 | opts.tags.tags.forEach(tag => {
38 | tag._id = tag._id || (Math.floor(Math.random() * 60466175) + 1679615).toString(36);
39 | });
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/dist/rg-toast/rg-toasts.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-toasts', '', '', '', function(opts) {
2 | opts.toasts = opts.toasts || {};
3 | if (!Array.isArray(opts.toasts.toasts)) opts.toasts.toasts = [];
4 | this.on("mount", () => this.update());
5 |
6 | this.toastClicked = e => {
7 | let toast = e.item;
8 | window.clearTimeout(toast.timer);
9 | toast.isvisible = false;
10 | this.trigger('select', toast);
11 | };
12 |
13 | let _uid = 1;
14 |
15 | const uid = () => _uid++;
16 |
17 | this.on('update', () => {
18 | opts.toasts.position = opts.toasts.position || 'bottomright';
19 | opts.toasts.toasts.forEach(toast => {
20 | if (typeof toast.isvisible == 'undefined') toast.isvisible = true;
21 | toast.id = toast.id || uid();
22 |
23 | if (!toast.timer && !toast.sticky) {
24 | toast.startTimer = () => {
25 | toast.timer = window.setTimeout(() => {
26 | toast.isvisible = false;
27 | this.trigger('close', toast);
28 | this.update();
29 | }, toast.timeout || 6000);
30 | };
31 |
32 | toast.startTimer();
33 | }
34 | });
35 | opts.toasts.isvisible = opts.toasts.toasts.filter(toast => toast.isvisible).length > 0;
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/dist/rg-toggle/rg-toggle.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-toggle', '', '', '', function(opts) {
2 | opts.toggle = opts.toggle || {};
3 |
4 | this.toggle = () => {
5 | opts.toggle.checked = !opts.toggle.checked;
6 | this.trigger('toggle', opts.toggle.checked);
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/dist/rg-unsplash/rg-unsplash.js:
--------------------------------------------------------------------------------
1 | riot.tag2('rg-unsplash', '
', '', '', function(opts) {
2 | this.on("mount", () => this.update());
3 | this.on('update', () => {
4 | if (!opts.unsplash) opts.unsplash = {};
5 | const {
6 | greyscale,
7 | width,
8 | height
9 | } = opts.unsplash;
10 | this.path = `${greyscale ? 'g/' : ''}${width || 450}/${height || 250}`;
11 | this.options = '';
12 | if (opts.unsplash.random) this.options += 'random&';
13 | if (opts.unsplash.blur) this.options += 'blur&';
14 | if (opts.unsplash.image) this.options += 'image=' + opts.unsplash.image + '&';
15 | if (typeof opts.unsplash.gravity !== 'undefined') this.options += 'gravity=' + opts.unsplash.gravity;
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/dist/rg.min.js:
--------------------------------------------------------------------------------
1 | riot.tag2("rg-alerts",'',"","",function(t){this.on("mount",()=>this.update()),this.on("update",()=>{t.alerts&&t.alerts.forEach(t=>{void 0===t.isvisible&&(t.isvisible=!0),t.timeout&&(t.startTimer=(()=>{t.timer=setTimeout(()=>{this.dismiss({item:t})},t.timeout)}),t.startTimer())})}),this.dismiss=(t=>{const a=t.item;a.isvisible=!1,clearTimeout(a.timer),this.trigger("dismiss",a),this.update()}),this.select=(t=>{const a=t.item;a.onclick&&a.onclick(a),this.trigger("select",a)})}),riot.tag2("rg-bubble",'','rg-bubble .context,[data-is="rg-bubble"] .context,rg-bubble .content,[data-is="rg-bubble"] .content{ display: inline-block; position: relative; } rg-bubble .bubble,[data-is="rg-bubble"] .bubble{ position: absolute; top: -70px; left: 50%; transform: translate3d(-50%, 0, 0); }',"",function(t){this.showBubble=(()=>{clearTimeout(this._timer),this.isvisible=!0}),this.hideBubble=(()=>{this._timer=setTimeout(()=>{this.isvisible=!1,this.update()},1e3)}),this.toggleBubble=(()=>{this.isvisible=!this.isvisible})}),riot.tag2("rg-chart","",'rg-chart,[data-is="rg-chart"]{ display: inline-block; width: 100%; }',"",function(t){Chart.defaults.global.responsive=!0,this.on("mount",()=>{a()}),this.on("loaded",t=>{this.on("unmount",()=>{t.destroy()})});const a=()=>{if(!t.chart)return;let a=this.root.querySelector("canvas").getContext("2d"),e=new Chart(a),i=null;switch(t.chart.type){case"line":i=e.Line(t.chart.data,t.chart.options);break;case"radar":i=e.Radar(t.chart.data,t.chart.options);break;case"polar":i=e.PolarArea(t.chart.data,t.chart.options);break;case"pie":i=e.Pie(t.chart.data,t.chart.options);break;case"doughnut":i=e.Doughnut(t.chart.data,t.chart.options);break;default:i=e.Bar(t.chart.data,t.chart.options)}this.trigger("loaded",i)}}),riot.tag2("rg-code",'','rg-code .editor,[data-is="rg-code"] .editor{ position: absolute; top: 0; right: 0; bottom: 0; left: 0; }',"",function(t){let a;t.editor||(t.editor={code:""});this.on("update",()=>{this.isMounted&&(a.setTheme(`ace/theme/${t.editor.theme||"monokai"}`),a.getSession().setMode(`ace/mode/${t.editor.mode||"html"}`),a.getSession().setTabSize(t.editor.tabsize||2),a.getSession().setUseSoftTabs(t.editor.softtabs),a.getSession().setUseWrapMode(t.editor.wordwrap),a.setReadOnly(t.editor.readonly),t.editor.code!=a.getValue()&&a.setValue(t.editor.code,1))}),this.on("mount",()=>{if(t.editor.code=t.editor.code||"",this.editor=a=ace.edit(this.root.querySelector(".editor")),a.$blockScrolling=1/0,t.editor.url){const a=new XMLHttpRequest;a.onload=(a=>{t.editor.code=a,this.update()}),a.open("get",t.editor.url,!0),a.send()}a.setValue(t.editor.code,1),a.getSession().on("change",e=>{t.editor.code=a.getValue(),this.trigger("onchange",a.getValue())}),this.update()})}),riot.tag2("rg-credit-card-number",'','rg-credit-card-number .card-no,[data-is="rg-credit-card-number"] .card-no{ padding-right: 60px; background-repeat: no-repeat; background-position: right center; background-size: 60px; } rg-credit-card-number .amex,[data-is="rg-credit-card-number"] .amex{ background-image: url(img/amex.png); } rg-credit-card-number .diners_club,[data-is="rg-credit-card-number"] .diners_club{ background-image: url(img/diners_club.png); } rg-credit-card-number .discover,[data-is="rg-credit-card-number"] .discover{ background-image: url(img/discover.png); } rg-credit-card-number .jcb,[data-is="rg-credit-card-number"] .jcb{ background-image: url(img/jcb.png); } rg-credit-card-number .mastercard,[data-is="rg-credit-card-number"] .mastercard{ background-image: url(img/mastercard.png); } rg-credit-card-number .visa,[data-is="rg-credit-card-number"] .visa{ background-image: url(img/visa.png); }',"",function(t){this.on("mount",()=>{this.input=this.root.querySelector("input"),this.input.value=t.card.cardnumber,this.update()}),this.oninput=(()=>{}),t.card||(t.card={cardnumber:""}),this.on("update",()=>{if(!this.isMounted)return;t.card.cardnumber=this.input.value;const a=function(t){var a,e,i,s,o,n,r;(e=[{name:"amex",icon:"images/amex.png",pattern:/^3[47]/,valid_length:[15]},{name:"diners_club",icon:"images/diners_club.png",pattern:/^30[0-5]/,valid_length:[14]},{name:"diners_club",icon:"images/diners_club.png",pattern:/^36/,valid_length:[14]},{name:"jcb",icon:"images/jcb.png",pattern:/^35(2[89]|[3-8][0-9])/,valid_length:[16]},{name:"laser",pattern:/^(6304|670[69]|6771)/,valid_length:[16,17,18,19]},{name:"visa_electron",pattern:/^(4026|417500|4508|4844|491(3|7))/,valid_length:[16]},{name:"visa",icon:"images/visa.png",pattern:/^4/,valid_length:[16]},{name:"mastercard",icon:"images/mastercard.png",pattern:/^5[1-5]/,valid_length:[16]},{name:"maestro",pattern:/^(5018|5020|5038|6304|6759|676[1-3])/,valid_length:[12,13,14,15,16,17,18,19]},{name:"discover",icon:"images/discover.png",pattern:/^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,valid_length:[16]}]).map(t=>t.name);return i=function(t){return e.find(a=>t.match(a.pattern))||null},o=function(t){var a,e,i,s,o,n;for(i=0,e=s=0,o=(n=t.split("").reverse()).length;s Mo
Tu
We
Th
Fr
Sa
Su
','rg-date .container,[data-is="rg-date"] .container{ position: relative; display: inline-block; cursor: pointer; } rg-date .calendar,[data-is="rg-date"] .calendar{ position: absolute; min-width: 300px; margin-top: .5em; left: 0; }',"",function(t){const a=t=>(moment.isMoment(t)||(t=moment(t)),t.isValid()?t:moment()),e=t=>{this.root.contains(t.target)||this.close(),this.update()};this.dayObj=(a=>{return{date:a||moment(),selected:t.date.date.isSame(a,"day"),today:moment().isSame(a,"day"),disabled:t.date.min&&t.date.min.isAfter(a)||t.date.max&&t.date.max.isBefore(a)}});const i=()=>{this.format="LL",this.yearFormat="YYYY",this.monthFormat="MMMM",this.dayFormat="DD",this.days=[],this.startBuffer=[],this.endBuffer=[];const a=moment(t.date.date).startOf("month"),e=moment(t.date.date).daysInMonth(),i=moment(t.date.date).endOf("month");for(let t=a.isoWeekday()-1;t>0;t-=1){const e=moment(a).subtract(t,"days");this.startBuffer.push(this.dayObj(e))}for(let t=0;t{t.date||(t.date={date:moment()}),t.date.date||(t.date.date=moment()),t.date.date=a(t.date.date),t.date.min=a(t.date.min||-864e13),t.date.min.isAfter(t.date.date,"day")&&(t.date.date=moment(t.date.min)),t.date.max=a(t.date.max||864e13),t.date.max.isBefore(t.date.date,"day")&&(t.date.date=moment(t.date.max)),document.addEventListener("click",e),this.update()}),this.on("update",()=>{this.isMounted&&(t.date.date=a(t.date.date),i(),this.value=t.date.date.format(this.format))}),this.on("unmount",()=>{document.removeEventListener("click",e)}),this.open=(()=>{this.isvisible=!0,this.trigger("open")}),this.close=(()=>{this.isvisible&&(this.isvisible=!1,this.trigger("close"))}),this.select=(a=>{t.date.date=a.item.day.date,this.trigger("select",t.date.date)}),this.setToday=(()=>{t.date.date=moment(),this.trigger("select",t.date.date)}),this.prevYear=(()=>{t.date.date=t.date.date.subtract(1,"year")}),this.nextYear=(()=>{t.date.date=t.date.date.add(1,"year")}),this.prevMonth=(()=>{t.date.date=t.date.date.subtract(1,"month")}),this.nextMonth=(()=>{t.date.date=t.date.date.add(1,"month")})}),riot.tag2("rg-drawer",' ',"","",function(t){t.drawer||(t.drawer={}),this.close=(()=>{t.drawer.isvisible=!1,this.trigger("close")}),this.select=(a=>{t.drawer.items.forEach(t=>t.active=!1),a.item.active=!0,this.trigger("select",a.item)})}),riot.tag2("rg-ga","","","",function(t){var a,e,i,s,o,n;a=window,e=document,i="script",s="ga",a.GoogleAnalyticsObject=s,a.ga=a.ga||function(){(a.ga.q=a.ga.q||[]).push(arguments)},a.ga.l=1*new Date,o=e.createElement(i),n=e.getElementsByTagName(i)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(o,n),ga("create",t.property,"auto"),ga("send","pageview")}),riot.tag2("rg-iframify",'','rg-iframify .iframify,[data-is="rg-iframify"] .iframify{ margin: 0; padding: 0; } rg-iframify iframe,[data-is="rg-iframify"] iframe{ position: relative; width: 100%; border: 0; }',"",function(t){this.on("mount",()=>{iframify(this.root.querySelector(".frame"),this.opts)})}),riot.tag2("rg-include"," {responseText}
","","",function(t){const a=()=>{const a=new XMLHttpRequest;a.onload=(e=>{t.include.unsafe?this.root.innerHTML=a.responseText:this.responseText=a.responseText,this.update(),this.trigger("loaded")}),a.open("get",t.include.url,!0),a.send(),this.trigger("loading")};this.on("mount",()=>{a()})}),riot.tag2("rg-map",'','rg-map .rg-map,[data-is="rg-map"] .rg-map{ margin: 0; padding: 0; width: 100%; height: 100%; } rg-map .rg-map img,[data-is="rg-map"] .rg-map img{ max-width: inherit; }',"",function(t){window.rg=window.rg||{},window.rg.gmap=riot.observable({initialize:()=>{window.rg.gmap.trigger("initialize")}}),this.on("mount",()=>{if(t.map||(t.map={center:{lat:53.806,lng:-1.535},zoom:7}),rg.gmap.on("initialize",()=>{t.map.mapObj=new google.maps.Map(this.root.querySelector(".rg-map"),t.map),this.trigger("loaded",t.map.mapObj)}),!document.getElementById("gmap_script")){let t=document.createElement("script");t.setAttribute("id","gmap_script"),t.type="text/javascript",t.src="https://maps.googleapis.com/maps/api/js?callback=window.rg.gmap.initialize",document.body.appendChild(t)}})}),riot.tag2("rg-markdown","","","",function(t){this.on("mount",()=>this.update()),this.reader=new commonmark.Parser,this.writer=new commonmark.HtmlRenderer,this.on("update",()=>{if(t.markdown||(t.markdown={}),t.markdown.content)this.root.innerHTML=this.writer.render(this.reader.parse(t.markdown.content));else if(t.markdown.url){const a=new XMLHttpRequest;a.onload=(t=>{this.root.innerHTML=this.writer.render(this.reader.parse(a.responseText)),this.trigger("loaded")}),a.open("get",t.markdown.url,!0),a.send(),this.trigger("loading")}})}),riot.tag2("rg-modal",' ','rg-modal .modal--ghost .modal__footer .button,[data-is="rg-modal"] .modal--ghost .modal__footer .button{ margin: 0 .5em 0 0; }',"",function(t){t.modal||(t.modal={}),this.close=(()=>{t.modal.dismissable&&(t.modal.isvisible=!1,this.trigger("close"))})}),riot.tag2("rg-pagination",'',"","",function(t){t.pagination||(t.pagination={pages:1,page:1}),this.on("page",()=>{const t=this.root.querySelectorAll("button");for(let a=0;a{t.pagination.page++,this.trigger("page",t.pagination.page)}),this.back=(()=>{t.pagination.page--,this.trigger("page",t.pagination.page)}),this.first=(()=>{t.pagination.page=1,this.trigger("page",t.pagination.page)}),this.last=(()=>{t.pagination.page=t.pagination.pages,this.trigger("page",t.pagination.page)})}),riot.tag2("rg-phone-sim",'
','rg-phone-sim .emulator,[data-is="rg-phone-sim"] .emulator{ position: relative; width: 365px; height: 792px; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW0AAAMYCAMAAAA3r0ZLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwBQTFRFMDk6+vr6KTM0lJucMz4/PklKJS8wLTg5Qk1OxsjILzo7gomJ2NvbdH5/ho2O9fb2KzY3ztHRPEdIOkVGZWxtjJSVOEJDkpeYWGRluL2+KTQ1vcHBoaWlPUZHcnp6nKKjOkRF1NfXqa2tp62tZnBxanV2VmFiZ29wVl1eaXJzbXR04uTktbq7QElK1tnZipKTi5CRTlZXpKioo6mqXmlqUVlaOEFCSVFSUFxdISssT1tcTlpbJC4vIiwtTVlaJjAxIy0uTFhZS1dYJzEyKDIzSlZXPUhJOURFO0ZHSVVWKzU2P0pLKjQ1OENEND0+QEtMLDY3SFRVN0JDQ05PLTc4ND9ANUBBQUxNNkFCR1NUMTo7RE9QLjg5N0BBR1JTRlJTLzk6RVFSMjs8RVBRRlFSNj9AMzw9SFNUMj0+IissMTs8MDo7SVRVRFBRMDs8MTw9IiwsMz0+Mjw9SlVWQ09QLjk6NT4/S1ZXND4/JC4uQU1OIy0tQk5PTFdYTVhZQExNTllaJS8vJzIyP0tMLzg5LDc4KDMzNT9AKjU1N0FCNkBBJjAwIywtMDs7Mj09NkFBJjExLjk5LDc3N0JCNUBAKjU2MTw8LDU2Ljc4OUNEKDEyQU1NPEhIPEhJO0dHOkZGND8/Qk5ORFBQQ09PLTY3OUREPkpKPkpLPUlJT1pbP0tLJTAwPUlKJzAxKjM07u/vKTIzsbW2YGprtLm50tXWPkhJo6endn+A3d/f6uvreoOEg4yN2tvc/Pz8n6am8/T0VFtcm6CgJS4v4OLi5ufnYGdncnt8dHp7gYaHJC0uu8DAjJGRQkxNxMfHKzQ1YGtsS1NUaXN0bnh5yMzMyszMy83Oy8/PdoCAKDIy7O3tT1dYuLu70NTUbXd46Onq6erreoCA2dzc8PHx8vPz5OXlnaSkn6Wmqq6ucHZ2t7y8o6eoeoSEkJaWm5+gW2ZnZG5vqa+wOEFB09bWtru7qrCwcXd4t7u83eDgzM7O7/DwNT4+7e7uwMPDwcPEeH5/////70wnUQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAA+NSURBVHja7N13nBTlGcDxEQI5AmJQBAkcnqhEDIhoWMt5iogmQbOaYNrqYrJh16gplmTVkILJpYCmF+DSE1JIcjRR7L333ntPYjQxvTl55tnr7N7t7uw+vDP3+/0x3G3hs5+vr++8M7s7eH75Xb5x+rOjN017aeq+tO++U1+atmn0s9M3Xl6BoFfm466ZOPROhIt259CJ19RS++7LdgW133a97O7aaI/a+VE0y+jRnUeF1p6wqfvvaz6+YVjT0jMyJ3rkeSdmzljaNKzh+OZuoE0TQmmvv67zLzrwmMY8wkXLNx5zYCfTdeur1p6wdeegblgKar8tbegc4lv/rirtjTMLT99/UVMKzgFLNS3avwA2c2Pl2n8tPHV1QxLJMks2rC6g/alC7ScvKozrhhyIFZRrKIzvi56sRHt94b/RIsZ1xeN7UYFuffna4/UJB68Er4rGHax648vUfmqkPnxBBrmqyixQv5FPlaP9Dz2eWdIEW9U1LdFjnQsG1n5ETz4dyowdavY+VE9XPTKQ9phddPfICjvk6lt3lruM6V97j132l26BK3S3BJAv79Gf9jN3BY85HKsadHhAedebSmtf+ofgEcOQqknDAsyLLi2pPTq4/0icatSRAefoUto7Bvc2oFSzGgLQHYtr3xTct5DVSA1XJgsD0puKaa99s9wzlwPImh5WzhXTl/5TRHt7uaN5GUI1bVmzqL64ufZfgkF/GD417rCA9e99tf8VzCPHoVPzjhPXaVv10d5bblzCyZE6nDIJ5pKde2u/Egz487Cp1zHlHr20h8otp50ETT2WgaeL7dCe2vcF/uOQqUsrA9z7emgHQ3thdEZLLpeL0kHYwq7BrdqjAv2ofEAnlU0EZaPjvTTgHdWlvXeEhnYu0VkuUoN7707tbW6X35oiciyc6C4yZxmaxPf2bTq0z5VfTo/IC8/20M5GZnAHy5JzO7Tvj85bCKlEzyIzdQdvLNxf0L4wmMQjMgnmemlHZubOBcQXqvb0CO0jk720o3OmIdhPTlft4FTrth5ju55tK8bbq/YG+emUiLzqTC/t6Lz1cYoYbwi0r47QisTz0j2w0xE6ngxWJVeLdrD+WxCZVx3J9ba0QNeAnj9T/twuOi87GcF9pLSdKM8U7Q2rV6+O0jcQMoXJJB2t96tzorzB99Y2NzfPjdQL9zLJZDJynw2YK85rvZ1ku9Cjuq+4xXknb4Js+XxU/WsQ5wnec7LlDcn6d544P+ddLFu+zlT/Vorzxd5k2fIJqfq3TJwney/Lls+RGBwniPPL3g6y5aOWBstWcd7BmypbLjhS/1LiPNWTTTMWBik02mijTWijTWijjTbFVTuZTqSTRW8OUzqJdpGyxT89mU2ELYv25kO4+LvnyUT4kmj3LV38YzjpGmin3dReIm2pF9BlU+LmMDmnrdBbUntQje0trj2o5m2FPlBiTWKQQm9R7cG03nZAexCFNtpoE9poE9poo01oo01oo01oo4021VT7MxIUBik02mijTeG1D5agMEih0UYbbUIbbUIbbbQJbbQJbbQJbbTRplppf1qCwiCFRhtttCm89lwJCoMUGm200Sa00Sa00Uab0Eab0Eab0EY73tqnS1AYpNBoo402hdc+VILCIIVGG220CW20CW200Sa00Sa00aYC9GkSFAYpNNpoo01oR0v7bRIUBik02mijTWijTWijjTahjTah7bL2hyUoDFJotNFGm9BGm0ppv0OCwiCFRhtttAlttAlttNEmtOOhfbwEhUEKjTbaaBPaaBPaLmi/T4LCIIVGG220CW20CW200ab6aS+UoDBIodFGG21CG21C2wXt4yQoDFJotNFGm9BGm9BGe7BpL5KgMEih0UYbbUIbbULbBe0PSFAYpNBoo402oY02oY32YNP+oASFQQqNNtpoE9poE9poDzbtj0hQGKTQaKONNqGNNpXS/qkEhUEKfYwEhUEKjTbaaBPaaBPaaA827Y9LUBik0GijjTahHS3tn0lQGKTQCyQoDFJotNFGm9BGm9BGG22qn/anJCgMUmi00Uabwmv/RILCIIVukKAwSKHRRhttQhttQhtttKl+2p+UoDBIodFGG20Kr/09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\'); background-repeat: no-repeat; background-position: center; background-size: cover; } rg-phone-sim .screen,[data-is="rg-phone-sim"] .screen{ position: absolute; top: 105px; left: 22px; background-color: white; width: 320px; height: 568px; border: 0; }',"",function(t){}),riot.tag2("rg-placeholdit",'
',"","",function(t){t.placeholdit||(t.placeholdit={}),this.on("mount",()=>this.update()),this.on("update",()=>{t.placeholdit.width=t.placeholdit.width||450,t.placeholdit.height=t.placeholdit.height||250,t.placeholdit.background=t.placeholdit.background||"000",t.placeholdit.color=t.placeholdit.color||"fff",t.placeholdit.text=t.placeholdit.text||`${t.placeholdit.width} x ${t.placeholdit.height}`,t.placeholdit.textsize=t.placeholdit.textsize||30,t.placeholdit.format=t.placeholdit.format||"png"})}),riot.tag2("rg-raw","","","",function(t){this.on("mount",()=>this.update()),this.on("update",()=>{this.root.innerHTML=t.content||""})}),riot.tag2("rg-select",' ','rg-select .menu,[data-is="rg-select"] .menu{ position: absolute; }',"",function(t){t.select||(t.select={options:[]});const a=t=>{this.root.contains(t.target)||this.close(),this.update()};this.on("mount",()=>{document.addEventListener("click",a),this.update()}),this.on("unmount",()=>{document.removeEventListener("click",a)}),this.keydown=(t=>{const a=this.isvisible;if(this.open(),38===t.keyCode)this.navigate(-1),t.preventDefault();else if(40===t.keyCode)this.navigate(1),t.preventDefault();else if(13===t.keyCode){if(!a)return;const e=s()||this.options[0];e&&this.select({item:e}),this.close(),t.preventDefault()}else this._navigate(0)}),this.select=(a=>{a.item.text;i().value=a.item.text,this.trigger("select",a.item.text),t.onselect&&t.onselect(a.item,this),t.select.options.forEach(t=>t.selected=!1),a.item.selected=!0,this.close()}),this.navigate=(t=>{const{options:a}=this;let e=(a.findIndex(t=>t.active)+t)%a.length;e<0&&(e=a.length-1),this._navigate(e)}),this._navigate=(a=>{t.select.options.forEach(t=>t.active=!1);const e=this.options[a||0];e&&(e.active=!0)}),this.on("update",()=>{if(!this.isMounted)return;const a=e();if(this.options=t.select.options,t.select.filter&&a){const t=new RegExp(a,"i");this.options=this.options.filter(a=>a.text.match(t)),this.trigger("filter")}});const e=()=>i().value,i=()=>this.root.querySelector("input"),s=()=>this.options.find(t=>t.active);this.open=(t=>{this.isvisible=!0,this.trigger("open")}),this.close=(t=>{this.isvisible=!1,this.trigger("close")})}),riot.tag2("rg-tabs",' {text}
{include.responseText}
',"","",function(t){t.tabs||(t.tabs={}),this.on("mount",()=>this.update());const a=t=>{if(t.raw)return;const a=new XMLHttpRequest;a.onload=(e=>{t.raw=a.responseText,t.text=void 0,this.update(),this.trigger("loaded",t)}),a.open("get",t.include,!0),a.send(),this.trigger("loading",t)};this.open=(a=>{let e=a.item;e.disabled||e.active||(t.tabs.tabs.forEach(t=>{t.active=!1}),this.trigger("open",e),e.active=!0)}),this.on("update",()=>{Array.isArray(t.tabs.tabs)&&t.tabs.tabs.forEach(t=>{!t.disabled&&t.active&&t.include&&a(t)})})}),riot.tag2("rg-tags",'
','rg-tags .menu,[data-is="rg-tags"] .menu{ position: absolute; }',"",function(t){this.on("mount",()=>this.update()),t.tags||(t.tags={options:[],tags:[]}),t.tags.options||(t.tags.options=[]),t.tags.tags||(t.tags.tags=[]),this.select_opts=Object.assign({filter:!0},t.tags),this.select=((t,a)=>{this.addTag(t),this.trigger("select",t),this.root.querySelector("input").value="",this.update()}),this.addTag=(a=>{-1==t.tags.tags.indexOf(a)&&t.tags.tags.push(a)}),this.removeTag=(a=>{t.tags.tags=t.tags.tags.filter(t=>{if(t._id!=a.item._id)return t})}),this.on("update",()=>{t.tags.options.forEach(t=>{t._id=t._id||(Math.floor(60466175*Math.random())+1679615).toString(36)}),t.tags.tags.forEach(t=>{t._id=t._id||(Math.floor(60466175*Math.random())+1679615).toString(36)})})}),riot.tag2("rg-toasts",'',"","",function(t){t.toasts=t.toasts||{},Array.isArray(t.toasts.toasts)||(t.toasts.toasts=[]),this.on("mount",()=>this.update()),this.toastClicked=(t=>{let a=t.item;window.clearTimeout(a.timer),a.isvisible=!1,this.trigger("select",a)});let a=1;this.on("update",()=>{t.toasts.position=t.toasts.position||"bottomright",t.toasts.toasts.forEach(t=>{void 0===t.isvisible&&(t.isvisible=!0),t.id=t.id||(()=>a++)(),t.timer||t.sticky||(t.startTimer=(()=>{t.timer=window.setTimeout(()=>{t.isvisible=!1,this.trigger("close",t),this.update()},t.timeout||6e3)}),t.startTimer())}),t.toasts.isvisible=t.toasts.toasts.filter(t=>t.isvisible).length>0})}),riot.tag2("rg-toggle",'',"","",function(t){t.toggle=t.toggle||{},this.toggle=(()=>{t.toggle.checked=!t.toggle.checked,this.trigger("toggle",t.toggle.checked)})}),riot.tag2("rg-unsplash",'
',"","",function(t){this.on("mount",()=>this.update()),this.on("update",()=>{t.unsplash||(t.unsplash={});const{greyscale:a,width:e,height:i}=t.unsplash;this.path=`${a?"g/":""}${e||450}/${i||250}`,this.options="",t.unsplash.random&&(this.options+="random&"),t.unsplash.blur&&(this.options+="blur&"),t.unsplash.image&&(this.options+="image="+t.unsplash.image+"&"),void 0!==t.unsplash.gravity&&(this.options+="gravity="+t.unsplash.gravity)})});
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | const UNBUNDLED = {
2 | frameworks: ['mocha', 'sinon-chai'], // no riot
3 | files: [
4 | 'node_modules/moment/min/moment.min.js',
5 | 'node_modules/commonmark/dist/commonmark.min.js',
6 | 'node_modules/chart.js/Chart.min.js',
7 | 'node_modules/ace-builds/src-min-noconflict/ace.js',
8 | 'node_modules/jquery/dist/jquery.min.js',
9 | 'node_modules/credit-card-type/dist/js/app.built.min.js',
10 | 'dependencies/js/iframify.js',
11 | `dependencies/js/riot+compiler-${process.env.RIOT_VERSION}.min.js`,
12 | 'css.js',
13 | 'demo/_charts.js',
14 | 'test-helpers.js',
15 | 'dist/rg.min.js', // use compiled RiotGear
16 | 'tags/**/*.spec.js', // no tags, only tests
17 | { pattern: 'demo/inc.html', watched: false, included: false, served: true, nocache: false }
18 | ],
19 | }
20 |
21 | module.exports = function (config) {
22 | config.set({
23 | basePath: '',
24 | frameworks: ['mocha', 'sinon-chai', 'riot'],
25 | files: [
26 | 'node_modules/moment/min/moment.min.js',
27 | 'node_modules/commonmark/dist/commonmark.min.js',
28 | 'node_modules/chart.js/Chart.min.js',
29 | 'node_modules/ace-builds/src-min-noconflict/ace.js',
30 | 'node_modules/jquery/dist/jquery.min.js',
31 | 'node_modules/credit-card-type/dist/js/app.built.min.js',
32 | 'dependencies/js/iframify.js',
33 | 'css.js',
34 | 'demo/_charts.js',
35 | 'test-helpers.js',
36 | 'tags/**/*',
37 | { pattern: 'demo/inc.html', watched: false, included: false, served: true, nocache: false }
38 | ],
39 | preprocessors: {
40 | 'tags/**/*.spec.js': ['babel'],
41 | 'tags/**/*.tag': ['riot', 'coverage']
42 | },
43 | riotPreprocessor: {
44 | options: {
45 | type: 'es6'
46 | }
47 | },
48 | logLevel: config.LOG_ERROR,
49 | reporters: ['mocha', 'coverage'],
50 | coverageReporter: {
51 | reporters: [{
52 | type: 'html',
53 | dir: 'coverage/'
54 | }, {
55 | type: 'text-summary'
56 | }],
57 | },
58 | browsers: ['ChromeHeadless'],
59 | singleRun: true
60 | })
61 |
62 | if (process.env.RIOT_VERSION) {
63 | config.set(UNBUNDLED)
64 | }
65 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "riotgear",
3 | "version": "3.6.0",
4 | "description": "The open source component library for RiotJS",
5 | "main": "dist/rg.min.js",
6 | "files": [
7 | "dist"
8 | ],
9 | "scripts": {
10 | "preriot": "rm -rf dist",
11 | "riot": "riot tags dist --type es6",
12 | "postriot": "riot demo --type es6",
13 | "minify": "uglifyjs --output dist/rg.js dist/**/*",
14 | "uglify": "uglifyjs --compress --mangle --screw-ie8 --comment false --output dist/rg.min.js dist/**/*",
15 | "test": "karma start",
16 | "_test2": "RIOT_VERSION=2.6.9 yarn test",
17 | "_test3": "RIOT_VERSION=3.13.2 yarn test",
18 | "_test-all": "yarn test && yarn _test2 && yarn _test3",
19 | "test2": "yarn run dev && yarn _test2",
20 | "test3": "yarn run dev && yarn _test3",
21 | "dev": "npm run riot && npm run minify && npm run uglify",
22 | "build": "npm run dev && npm run _test-all",
23 | "demo": "mkdir -p _dist; cp -r demo/static/* _dist; yarn parcel serve demo/index.html --out-dir _dist"
24 | },
25 | "repository": {
26 | "type": "git",
27 | "url": "https://github.com/RiotGear/rg.git"
28 | },
29 | "keywords": [
30 | "riotjs",
31 | "riot",
32 | "webcomponents",
33 | "html5",
34 | "es6",
35 | "javascript",
36 | "tags",
37 | "components",
38 | "riotgear"
39 | ],
40 | "author": "Gregory Pratt",
41 | "license": "MIT",
42 | "bugs": {
43 | "url": "https://github.com/RiotGear/rg/issues"
44 | },
45 | "homepage": "https://riotgear.js.org/",
46 | "devDependencies": {
47 | "@babel/core": "^7.5.5",
48 | "@babel/preset-env": "^7.5.5",
49 | "ace-builds": "^1.2.2",
50 | "chai": "^4.2.0",
51 | "chart.js": "1.0.2",
52 | "commonmark": "^0.29.0",
53 | "jquery": "^3.4.1",
54 | "karma": "^4.2.0",
55 | "karma-babel-preprocessor": "^8.0.1",
56 | "karma-chrome-launcher": "^3.0.0",
57 | "karma-coverage": "^1.1.2",
58 | "karma-mocha": "^1.3.0",
59 | "karma-mocha-reporter": "^2.2.5",
60 | "karma-riot": "^2.0.0",
61 | "karma-sinon-chai": "^2.0.2",
62 | "mocha": "^6.2.0",
63 | "mocha-snapshot": "^1.0.0",
64 | "moment": "^2.24.0",
65 | "normalize.css": "^8.0.1",
66 | "parcel": "^1.12.3",
67 | "parcel-plugin-riot": "^2.1.0",
68 | "puppeteer": "^1.19.0",
69 | "riot": "3.13.2",
70 | "sinon": "^7.3.2",
71 | "sinon-chai": "2.8.0",
72 | "uglify-es": "^3.3.9"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tags/rg-alerts/rg-alerts.blank.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-alerts blank', function() {
2 | let tag
3 |
4 | beforeEach(function() {
5 |
6 | $('body').append('')
7 | tag = riot.mount('rg-alerts')[0]
8 | })
9 |
10 | after(function() {
11 | tag.unmount()
12 | })
13 |
14 | it('is mounted', function() {
15 | tag.isMounted.should.be.true
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/tags/rg-alerts/rg-alerts.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-alerts', function () {
2 | let tag, oncloseSpy, onclickSpy
3 | const seconds = 500
4 |
5 | beforeEach(function () {
6 | oncloseSpy = sinon.spy()
7 | onclickSpy = sinon.spy()
8 | $('body').append('')
9 | let alerts = [{
10 | type: 'error',
11 | content: 'Error! Something bad happened.',
12 | onclick: onclickSpy,
13 | dismissable: true
14 | }, {
15 | type: 'secondary',
16 | content: 'Warning! Something sort of bad happened.',
17 | dismissable: false
18 | }, {
19 | type: 'primary',
20 | content: 'Look! Something you should know about.',
21 | timeout: seconds
22 | }, {
23 | type: 'success',
24 | content: 'Success! Well done.',
25 | timeout: seconds
26 | }]
27 |
28 | tag = riot.mount('rg-alerts', {
29 | alerts
30 | })[0]
31 |
32 | tag.on('dismiss', oncloseSpy)
33 | })
34 |
35 | afterEach(function () {
36 | tag.unmount()
37 | })
38 |
39 | it('is mounted', function () {
40 | tag.isMounted.should.be.true
41 | })
42 |
43 | it('displays correct number of alerts', function () {
44 | $('rg-alerts .alerts__alert').length.should.equal(4)
45 | })
46 |
47 | it('displays correct type of alerts', function () {
48 | $('rg-alerts .alerts__alert:nth-child(1)').is('.alerts__alert--error').should.be.true
49 | $('rg-alerts .alerts__alert:nth-child(2)').is('.alerts__alert--secondary').should.be.true
50 | $('rg-alerts .alerts__alert:nth-child(3)').is('.alerts__alert--primary').should.be.true
51 | $('rg-alerts .alerts__alert:nth-child(4)').is('.alerts__alert--success').should.be.true
52 | })
53 |
54 | it('can not be dismissed if set', function () {
55 | $('rg-alerts .alerts__alert:nth-child(2)').find('.button--close').length.should.equal(0)
56 | })
57 |
58 | it('can be dismissed', function () {
59 | $('rg-alerts .alerts__alert:nth-child(3)').find('.button--close').click()
60 | $('rg-alerts .alerts__alert').length.should.equal(3)
61 | oncloseSpy.should.have.been.called
62 | })
63 |
64 | it('calls the onclose function when dismissed', function () {
65 | $('rg-alerts .alerts__alert:nth-child(1)').find('.button--close').click()
66 | oncloseSpy.should.have.been.called
67 | onclickSpy.should.have.been.called
68 | })
69 |
70 | it('disappears after timer runs down', function (done) {
71 | setTimeout(function () {
72 | $('rg-alerts .alerts__alert').length.should.equal(2)
73 | done()
74 | }, seconds)
75 | })
76 |
77 | it('calls the onclose function when automatically dismissed', function (done) {
78 | setTimeout(function () {
79 | oncloseSpy.should.have.been.called
80 | done()
81 | }, seconds)
82 | })
83 | })
84 |
85 | describe('rg-alerts no opts', function () {
86 | let tag
87 |
88 | beforeEach(function () {
89 |
90 | $('body').append('')
91 | tag = riot.mount('rg-alerts')[0]
92 | })
93 |
94 | after(function () {
95 | tag.unmount()
96 | })
97 |
98 | it('is mounted', function () {
99 | tag.isMounted.should.be.true
100 | })
101 | })
102 |
--------------------------------------------------------------------------------
/tags/rg-alerts/rg-alerts.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 | { text }
9 |
10 |
11 |
12 |
46 |
47 |
--------------------------------------------------------------------------------
/tags/rg-audio/rg-audio.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
--------------------------------------------------------------------------------
/tags/rg-bubble/rg-bubble.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-bubble', function() {
2 | let tag, bubble
3 | const text = 'This is a bubble'
4 |
5 | beforeEach(function() {
6 | $('body').append(``)
7 | tag = riot.mount('rg-bubble', {
8 | bubble: {
9 | text
10 | }
11 | })[0]
12 | })
13 |
14 | afterEach(function () {
15 | tag.unmount()
16 | })
17 |
18 | it('is mounted', function() {
19 | tag.isMounted.should.be.true
20 | })
21 |
22 | describe('displays tooltip with correct text', function() {
23 | it('on click', function() {
24 | $('rg-bubble .content').trigger('click')
25 | $('rg-bubble .bubble').length.should.equal(1)
26 | $('rg-bubble .bubble').html().should.contain(text)
27 | })
28 |
29 | it('on mouse over', function() {
30 | $('rg-bubble .content')[0].dispatchEvent(new Event("mouseover"))
31 | $('rg-bubble .bubble').length.should.equal(1)
32 | $('rg-bubble .bubble').html().should.contain(text)
33 | })
34 | })
35 |
36 | describe('hides tooltip', function() {
37 | beforeEach(function() {
38 | $('rg-bubble .content').trigger('click')
39 | })
40 |
41 | it('on click', function() {
42 | $('rg-bubble .content').trigger('click')
43 | $('rg-bubble .bubble').length.should.equal(0)
44 | })
45 |
46 | describe('after 1 second', function() {
47 | it('on mouse out', function(done) {
48 | $('rg-bubble .content')[0].dispatchEvent(new Event("mouseout"))
49 | setTimeout(function() {
50 | $('rg-bubble .bubble').length.should.equal(0)
51 | done()
52 | }, 1000)
53 | })
54 | })
55 | })
56 | })
57 |
58 | describe('rg-bubble no opts', function() {
59 | let tag
60 |
61 | beforeEach(function() {
62 |
63 | $('body').append('')
64 | tag = riot.mount('rg-bubble')[0]
65 | })
66 |
67 | after(function() {
68 | tag.unmount()
69 | })
70 |
71 | it('is mounted', function() {
72 | tag.isMounted.should.be.true
73 | })
74 | })
75 |
--------------------------------------------------------------------------------
/tags/rg-bubble/rg-bubble.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | { opts.bubble.text }
6 |
7 |
8 |
9 |
10 |
11 |
12 |
29 |
30 |
44 |
45 |
--------------------------------------------------------------------------------
/tags/rg-chart/rg-chart.spec.js:
--------------------------------------------------------------------------------
1 | // not the most thorough test. It only verifies that the charts in the demo don't throw errors
2 |
3 | describe('rg-chart', function () {
4 | $('body').append('')
5 | it('is mounted', function () {
6 | const tag2 = newTag("rg-chart")
7 | tag2.isMounted.should.be.true
8 | })
9 |
10 | Object.keys(window._charts).forEach( key => {
11 | it('is mounted: '+key, function () {
12 | const tag = riot.mount("rg-chart", { chart: window._charts[key] })[0]
13 | tag.isMounted.should.be.true
14 | })
15 | })
16 | })
--------------------------------------------------------------------------------
/tags/rg-chart/rg-chart.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
48 |
49 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/tags/rg-code/rg-code.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-code', function() {
2 | let tag, spy, editor
3 |
4 | const getOpts = extra => {
5 | const _default = {
6 | theme: 'monokai',
7 | mode: 'javascript',
8 | tabsize: '2',
9 | softtabs: 'true',
10 | wordwrap: 'true',
11 | readonly: 'true',
12 | onchange: spy
13 | }
14 | return Object.assign(_default, extra)
15 | }
16 |
17 | beforeEach(function() {
18 | spy = sinon.spy()
19 | })
20 |
21 | afterEach(function() {
22 | tag.unmount()
23 | })
24 |
25 | it('allows code for opts', function() {
26 | tag = newTag('rg-code', {
27 | editor: getOpts({ code: 'Hello world!
' })
28 | })
29 | tag.isMounted.should.be.true
30 | spy.should.not.have.been.called
31 | })
32 |
33 | it('allows url for opts', function(done) {
34 | mockAjax()
35 | tag = newTag('rg-code', {
36 | editor: getOpts({ url: 'yay.html' })
37 | })
38 | tag.isMounted.should.be.true
39 | setTimeout(() => {
40 | // gotta kick this into another thread to catch the faked ajax
41 | tag.root.innerText.should.equal('1\nYay!')
42 | unmockAjax()
43 | done()
44 | },0)
45 | })
46 | })
47 |
48 | describe('rg-code no opts', function() {
49 | let tag
50 |
51 | beforeEach(function() {
52 | $('body').append('')
53 | tag = riot.mount('rg-code')[0]
54 | })
55 |
56 | afterEach(function() {
57 | tag.unmount()
58 | })
59 |
60 | it('is mounted', function() {
61 | tag.isMounted.should.be.true
62 | })
63 | })
64 |
--------------------------------------------------------------------------------
/tags/rg-code/rg-code.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
50 |
51 |
61 |
62 |
--------------------------------------------------------------------------------
/tags/rg-credit-card/rg-credit-card-number.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
145 |
146 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/tags/rg-credit-card/rg-credit-card.spec.js:
--------------------------------------------------------------------------------
1 | // NOTE: No need to test the validator, its already done
2 | // https://github.com/PawelDecowski/jquery-creditcardvalidator
3 |
4 | describe('rg-credit-card-number', function () {
5 | let tag, cardNoVisa, cardNoMaestro, placeholder, card
6 | cardNoVisa = '4000 0000 0000 0002'
7 | cardNoMaestro = '5018 0000 0009'
8 | placeholder = '0123 4567 8910 1112'
9 |
10 | beforeEach(function () {
11 | card = {
12 | placeholder: placeholder,
13 | cardnumber: cardNoVisa
14 | }
15 |
16 | $('body').append('')
17 | tag = riot.mount('rg-credit-card-number', {
18 | card
19 | })[0]
20 | })
21 |
22 | afterEach(function () {
23 | tag.unmount()
24 | })
25 |
26 | it('is mounted', function () {
27 | tag.isMounted.should.be.true
28 | })
29 |
30 | it('populates textbox with provided value', function () {
31 | const textbox = $('rg-credit-card-number .card-no')
32 | textbox.val().should.equal(cardNoVisa)
33 | })
34 |
35 | it('sets the placeholder text correctly', function () {
36 | const textbox = $('rg-credit-card-number .card-no')
37 | textbox.attr('placeholder').should.equal(placeholder)
38 | })
39 |
40 | it('sets validation result', function () {
41 | card.valid.should.be.true
42 | })
43 |
44 | it('sets validation result on input', function () {
45 | $('rg-credit-card-number .card-no').val(cardNoMaestro).trigger('input')
46 | card.valid.should.be.true
47 | })
48 |
49 | describe('sets validation css classes', function () {
50 | it('for the icon', function () {
51 | const textbox = $('rg-credit-card-number .card-no')
52 | textbox.val(cardNoMaestro)
53 | tag.update()
54 | textbox.hasClass('maestro').should.be.true
55 | textbox.val(cardNoVisa)
56 | tag.update()
57 | textbox.hasClass('visa').should.be.true
58 | })
59 |
60 | it('for a valid number', function () {
61 | const textbox = $('rg-credit-card-number .card-no')
62 | textbox.val(cardNoVisa).trigger('input')
63 | textbox.hasClass('field--success').should.be.true
64 | })
65 | })
66 |
67 | it('has no icon for invalid number', function () {
68 | const textbox = $('rg-credit-card-number .card-no')
69 | textbox.hasClass('visa').should.be.true
70 | textbox.val('moekoaersntoeanrstoen')
71 | tag.update()
72 | textbox.trigger("input")
73 | textbox.hasClass('visa').should.be.false
74 | })
75 | })
76 |
77 | describe('rg-credit-card-number no opts', function () {
78 | let tag
79 |
80 | beforeEach(function () {
81 | $('body').append('')
82 | tag = riot.mount('rg-credit-card-number')[0]
83 | })
84 |
85 | afterEach(function () {
86 | tag.unmount()
87 | })
88 |
89 | it('is mounted', function () {
90 | tag.isMounted.should.be.true
91 | })
92 |
93 | it('is blank when no cardNo is specified', function () {
94 | const textbox = $('rg-credit-card-number .card-no')
95 | textbox.val().should.equal('')
96 | })
97 | })
98 |
--------------------------------------------------------------------------------
/tags/rg-date/rg-date.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-date', function () {
2 | let tag
3 | const DATE = "YYYY-MM-DD"
4 |
5 | afterEach(function() {
6 | tag.unmount()
7 | window.BEES = false
8 | })
9 |
10 | it('no opts', function () {
11 | tag = newTag('rg-date')
12 | tag.isMounted.should.be.true
13 |
14 | const dayObj = tag.dayObj()
15 | dayObj.today.should.be.true
16 | dayObj.selected.should.be.true
17 | should.equal(dayObj.disabled || false, false)
18 | })
19 |
20 | it('June 20th, 1999', function() {
21 | tag = newTag('rg-date', {
22 | date: {
23 | date: '1999-06-20',
24 | min: '1999-01-01',
25 | max: '1999-12-31',
26 | }
27 | })
28 |
29 | const dayObj = tag.dayObj()
30 | dayObj.today.should.be.true
31 | dayObj.selected.should.be.false
32 | dayObj.disabled.should.be.true // note: this test will fail if run in 1999
33 |
34 | const day2 = tag.dayObj('1999-06-20')
35 | day2.selected.should.be.true
36 | day2.disabled.should.be.false
37 | tag.dayObj('1998-12-31').disabled.should.be.true
38 | tag.dayObj('2000-01-01').disabled.should.be.true
39 | })
40 |
41 | it('detect triggers', function() {
42 | tag = newTag('rg-date', { date: { date: '1999-06-20'}})
43 | const validate = mySpy(tag, ['open','close','select'])
44 | tag.root.querySelector('input').click()
45 | validate({ open: 1})
46 | tag.root.querySelector(".calendar__date:nth-child(30)").click()
47 | validate({ select: 1, close: 1})
48 |
49 | // calling close again doesn't retrigger close event
50 | tag.close()
51 | validate()
52 | })
53 |
54 | it('other functions', function() {
55 | tag = newTag('rg-date', { date: { date: "1999-06-20" } })
56 | tag.prevYear()
57 | tag.opts.date.date.format(DATE).should.equal("1998-06-20")
58 | tag.nextYear()
59 | tag.opts.date.date.format(DATE).should.equal("1999-06-20")
60 | tag.prevMonth()
61 | tag.opts.date.date.format(DATE).should.equal("1999-05-20")
62 | tag.nextMonth()
63 | tag.opts.date.date.format(DATE).should.equal("1999-06-20")
64 | tag.setToday()
65 | tag.opts.date.date.format(DATE).should.equal(moment().format(DATE))
66 | })
67 |
68 | it('works with random defaults', function() {
69 | const today = moment().format(DATE)
70 | const ogwarn = console.warn
71 | console.warn = () => {} //suppress annoying moment output over the following diaster
72 | tag = newTag('rg-date', { date: { date: 'bees!' }})
73 | tag.opts.date.date.format(DATE).should.equal(today)
74 | console.warn = ogwarn
75 | tag.unmount()
76 |
77 | // no day (like today!)
78 | tag = newTag('rg-date', { date: { }})
79 | tag.opts.date.date.format(DATE).should.equal(today)
80 | tag.unmount()
81 |
82 | // date after max, will fail after the year 9000
83 | tag = newTag('rg-date', { date: { date: "9000-01-01", max: today }})
84 | tag.opts.date.date.format(DATE).should.equal(today)
85 | tag.unmount()
86 |
87 | // date before min, will fail before the year 1999
88 | tag = newTag('rg-date', { date: { date: "1999-01-01", min: today }})
89 | tag.opts.date.date.format(DATE).should.equal(today)
90 | tag.unmount()
91 | })
92 | })
93 |
--------------------------------------------------------------------------------
/tags/rg-date/rg-date.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Mo
16 |
Tu
17 |
We
18 |
Th
19 |
Fr
20 |
Sa
21 |
Su
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
158 |
159 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/tags/rg-drawer/rg-drawer.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-drawer', function () {
2 | let tag, drawer
3 | let onClickSpy = sinon.spy()
4 | let onCloseSpy = sinon.spy()
5 |
6 | beforeEach(function () {
7 | $('body').append('')
8 | drawer = {
9 | header: 'Side Menu',
10 | isvisible: true,
11 | items: [{
12 | text: 'Item 1'
13 | }, {
14 | text: 'Item 2'
15 | }]
16 | }
17 |
18 | tag = riot.mount('rg-drawer', {
19 | drawer
20 | })[0]
21 |
22 | tag.on('select', onClickSpy)
23 | .on('close', onCloseSpy)
24 | })
25 |
26 | afterEach(function () {
27 | tag.unmount()
28 | })
29 |
30 | it('is mounted', function () {
31 | tag.isMounted.should.be.true
32 | const tag2 = newTag("rg-drawer")
33 | tag2.isMounted.should.be.true
34 | tag2.unmount()
35 | })
36 |
37 | it('has an overlay', function () {
38 | $('rg-drawer .overlay').length.should.equal(1)
39 | $('rg-drawer .drawer').is('.drawer--visible').should.be.true
40 | })
41 |
42 | it('header is set correctly', function () {
43 | $('rg-drawer .heading').text().should.contain('Side Menu')
44 | })
45 |
46 | it('has items', function () {
47 | $('rg-drawer .menu__item').length.should.equal(2)
48 | $('rg-drawer .menu__item:nth-child(1)').text().should.contain('Item 1')
49 | $('rg-drawer .menu__item:nth-child(2)').text().should.contain('Item 2')
50 | })
51 |
52 | it('clicking an item activates it', function () {
53 | $('rg-drawer .menu__item:nth-child(1)').is('.menu__item--active').should.be.false
54 | $('rg-drawer .menu__item:nth-child(2)').is('.menu__item--active').should.be.false
55 | $('rg-drawer .menu__item:nth-child(1)').click()
56 | $('rg-drawer .menu__item:nth-child(1)').is('.menu__item--active').should.be.true
57 | $('rg-drawer .menu__item:nth-child(2)').is('.menu__item--active').should.be.false
58 | $('rg-drawer .menu__item:nth-child(2)').click()
59 | $('rg-drawer .menu__item:nth-child(1)').is('.menu__item--active').should.be.false
60 | $('rg-drawer .menu__item:nth-child(2)').is('.menu__item--active').should.be.true
61 | })
62 |
63 | it('clicking overlay closes draw', function () {
64 | $('rg-drawer .overlay').click()
65 | $('rg-drawer .overlay').length.should.equal(0)
66 | $('rg-drawer .drawer').is('.drawer--visible').should.be.false
67 | })
68 | })
69 |
--------------------------------------------------------------------------------
/tags/rg-drawer/rg-drawer.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{ opts.drawer.header }
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tags/rg-ga/rg-ga.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-ga', function() {
2 | let tag
3 |
4 | beforeEach(function() {
5 | window.ga = sinon.spy()
6 | $('body').append('')
7 | tag = riot.mount('rg-ga')[0]
8 | })
9 |
10 | afterEach(function() {
11 | tag.unmount()
12 | })
13 |
14 | it('is mounted', function() {
15 | tag.isMounted.should.be.true
16 | })
17 |
18 | it('ga should have been called twice', function () {
19 | window.ga.should.have.been.calledTwice
20 | window.ga.should.have.been.calledWith('create', 'a1b2c3d4', 'auto')
21 | window.ga.should.have.been.calledWith('send', 'pageview')
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/tags/rg-ga/rg-ga.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tags/rg-iframify/rg-iframify.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-iframify', function () {
2 | it('mounts', function() {
3 | const tag = newTag('rg-iframify')
4 | tag.isMounted.should.be.true
5 | })
6 | })
--------------------------------------------------------------------------------
/tags/rg-iframify/rg-iframify.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tags/rg-include/rg-include.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-include', function() {
2 | let tag, include
3 |
4 | beforeEach(function() {
5 | include = {
6 | url: 'inc.html'
7 | }
8 |
9 | $('body').append('')
10 | tag = riot.mount('rg-include', {
11 | include
12 | })[0]
13 | })
14 |
15 | afterEach(function() {
16 | tag.unmount()
17 | })
18 |
19 | it('is mounted', function() {
20 | tag.isMounted.should.be.true
21 | })
22 |
23 | it('handles unsafe', function(done) {
24 | setTimeout(function () {
25 | tag.responseText.should.equal('NOT FOUND')
26 | done()
27 | }, 1000)
28 | })
29 | })
30 |
31 | describe('rg-include unsafe', function() {
32 | let tag, include
33 |
34 | beforeEach(function() {
35 | include = {
36 | url: 'inc.html',
37 | unsafe: true
38 | }
39 |
40 | $('body').append('')
41 | tag = riot.mount('rg-include', {
42 | include
43 | })[0]
44 | })
45 |
46 | afterEach(function() {
47 | tag.unmount()
48 | })
49 |
50 | it('is mounted', function() {
51 | tag.isMounted.should.be.true
52 | })
53 |
54 | it('handles unsafe', function(done) {
55 | setTimeout(function () {
56 | tag.root.innerHTML.should.equal('NOT FOUND')
57 | expect(tag.responseText).to.not.exist
58 | done()
59 | }, 1000)
60 | })
61 | })
62 |
--------------------------------------------------------------------------------
/tags/rg-include/rg-include.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | { responseText }
5 |
6 |
7 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tags/rg-map/rg-map.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-map', function () {
2 | let tag
3 |
4 | afterEach(function () {
5 | tag.unmount()
6 | })
7 |
8 | it('is mounted', function () {
9 | $('body').append('')
10 | tag = riot.mount('rg-map')[0]
11 | tag.isMounted.should.be.true
12 | const tag2 = newTag('rg-map', { map: {}})
13 | tag2.isMounted.should.be.true
14 | tag2.unmount()
15 | })
16 |
17 | it('doesnt add map script tag twice', function () {
18 | $('body').append('')
19 | $('body').append('')
20 | tag = riot.mount('rg-map')[0]
21 | $('#gmap_script').length.should.equal(1)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/tags/rg-map/rg-map.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
38 |
39 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/tags/rg-markdown/rg-markdown.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-markdown', function() {
2 | let tag, markdown
3 | let spy = sinon.spy()
4 |
5 | afterEach(function() {
6 | tag.unmount()
7 | })
8 |
9 | it('is mounted', function() {
10 | tag = newTag('rg-markdown')
11 | tag.isMounted.should.be.true
12 | })
13 |
14 | it('renders HTML', function () {
15 | tag = newTag('rg-markdown', {
16 | markdown: { content: '**Some** other content' }
17 | })
18 | $('rg-markdown').html().should.contain('Some other content
')
19 | })
20 |
21 | it('renders url', function (done) {
22 | mockAjax()
23 | tag = newTag('rg-markdown')
24 | tag.opts.markdown.url = 'yay.html'
25 | tag.on('loaded', () => {
26 | $('rg-markdown').html().should.contain("Yay!
")
27 | unmockAjax()
28 | done()
29 | })
30 | tag.update()
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/tags/rg-markdown/rg-markdown.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tags/rg-modal/rg-modal.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-modal', function() {
2 | let tag
3 | let spyOnClose = sinon.spy()
4 | let spyOnClick = sinon.spy()
5 | let modal = {
6 | heading: 'Modal heading',
7 | isvisible: true,
8 | ghost: true,
9 | dismissable: false,
10 | buttons: [{
11 | action: spyOnClick,
12 | text: 'Save'
13 | }, {
14 | text: 'Cancel',
15 | style: 'color: cornflowerblue;'
16 | }]
17 | }
18 |
19 | beforeEach(function() {
20 | $('body').append('This is the body')
21 | tag = riot.mount('rg-modal', { modal: deepClone(modal) })[0]
22 | tag.on('close', spyOnClose)
23 | })
24 |
25 | afterEach(function() {
26 | spyOnClick.resetHistory()
27 | spyOnClose.resetHistory()
28 | tag.unmount()
29 | })
30 |
31 | it('is mounted', function() {
32 | tag.isMounted.should.be.true
33 | })
34 |
35 | it('has correct heading', function() {
36 | $('rg-modal .heading').text().should.equal(modal.heading)
37 | })
38 |
39 | it('has the correct body', function() {
40 | $('rg-modal .modal__body').html().should.contain('This is the body')
41 | })
42 |
43 | it('can be a ghost modal', function() {
44 | $('rg-modal .modal').is('.modal--ghost').should.be.true
45 | })
46 |
47 | it('close button can be turned off', function() {
48 | $('rg-modal .button--close').length.should.equal(0)
49 | })
50 |
51 | it('has a footer with two buttons', function() {
52 | $('rg-modal .modal__footer button').length.should.equal(2)
53 | $('rg-modal .modal__footer button:nth-child(1)').text().should.contain(modal.buttons[0].text)
54 | $('rg-modal .modal__footer button:nth-child(2)').text().should.contain(modal.buttons[1].text)
55 | })
56 |
57 | it('buttons can be styled', function() {
58 | $('rg-modal .modal__footer button:nth-child(2)').css('color').should.equal('rgb(100, 149, 237)')
59 | })
60 |
61 | it('calls the action on button click', function() {
62 | $('rg-modal .modal__footer button:nth-child(1)').click()
63 | spyOnClick.should.have.been.calledOnce
64 | })
65 |
66 | it('click the close button calls the onclose callback', function() {
67 | const _modal = deepClone(modal)
68 | _modal.dismissable = true
69 | tag = newTag("rg-modal",{ modal: _modal })
70 | tag.on('close', spyOnClose)
71 | tag.$('.button--close').click()
72 | tag.$$('.modal').length.should.equal(0)
73 | spyOnClose.should.have.been.calledOnce
74 | })
75 |
76 | it('is indismissible when indisimissible', function() {
77 | tag.close()
78 | spyOnClose.callCount.should.equal(0)
79 | })
80 |
81 | it('works with no opts', function() {
82 | newTag("rg-modal")
83 | })
84 | })
85 |
--------------------------------------------------------------------------------
/tags/rg-modal/rg-modal.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/tags/rg-pagination/rg-pagination.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-pagination', function() {
2 | let tag
3 | let spyOnPageChange = sinon.spy()
4 | let pagination = {
5 | pages: 100,
6 | page: 3
7 | }
8 |
9 | beforeEach(function() {
10 | $('body').append(' {
28 | tag.root.querySelector('.pagination__page--current').innerText.should.equal(i)
29 | }
30 | const getNavButtons = () => tag.root.querySelectorAll(".pagination__control")
31 | assertCurrent('3')
32 | getNavButtons()[1].click() // back one
33 | assertCurrent('2')
34 | getNavButtons()[2].click() // forward one
35 | assertCurrent('3')
36 | getNavButtons()[0].click() // start
37 | assertCurrent('1')
38 | getNavButtons()[3].click() // end
39 | assertCurrent('100')
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/tags/rg-pagination/rg-pagination.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
21 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/tags/rg-phone-sim/rg-phone-sim.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-phone-sim', function() {
2 | let tag, phonesim
3 |
4 | beforeEach(function() {
5 | $('body').append('')
6 | tag = riot.mount('rg-phone-sim', {
7 | phonesim: {
8 | url: 'http://riotjs.com/'
9 | }
10 | })[0]
11 | })
12 |
13 | afterEach(function() {
14 | tag.unmount()
15 | })
16 |
17 | it('is mounted', function() {
18 | tag.isMounted.should.be.true
19 | })
20 |
21 | it('has an iframe in an emulator', function() {
22 | $('rg-phone-sim .emulator iframe').length.should.be.equal(1)
23 | })
24 |
25 | it('iframe is pointed to url attribute', function() {
26 | $('rg-phone-sim iframe').attr('src').should.equal('http://riotjs.com/')
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/tags/rg-phone-sim/rg-phone-sim.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tags/rg-placeholdit/rg-placeholdit.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-placeholdit', function() {
2 | let tag, placeholdit
3 |
4 | beforeEach(function() {
5 | $('body').append('')
6 | tag = riot.mount('rg-placeholdit')[0]
7 | })
8 |
9 | afterEach(function() {
10 | tag.unmount()
11 | })
12 |
13 | it('is mounted', function() {
14 | tag.isMounted.should.be.true
15 | })
16 |
17 | it('has an img tag', function() {
18 | $('rg-placeholdit img').length.should.equal(1)
19 | })
20 |
21 | it('defaults options', function () {
22 | $('rg-placeholdit img').attr('src').should.equal('https://placeholdit.imgix.net/~text?bg=000&txtclr=fff&txt=450 x 250&txtsize=30&w=450&h=250&fm=png')
23 | })
24 |
25 | it('also alows specified options', function() {
26 | const tag2 = newTag("rg-placeholdit",{
27 | placeholdit: {
28 | width: 50,
29 | height: 60,
30 | background: "pink",
31 | color: "blue",
32 | text: "BOATS!",
33 | textsize: 35,
34 | format: "jpg",
35 | },
36 | })
37 | tag2.$('img').src.should.equal('https://placeholdit.imgix.net/~text?bg=pink&txtclr=blue&txt=BOATS!&txtsize=35&w=50&h=60&fm=jpg')
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/tags/rg-placeholdit/rg-placeholdit.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tags/rg-raw/rg-raw.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-raw', function() {
2 | it('is mounted', function() {
3 | const tag = newTag('rg-raw', {})
4 | tag.isMounted.should.be.true
5 | })
6 |
7 | it('contains the supplied html', function() {
8 | const tag = newTag('rg-raw', { content: 'Hello there' })
9 | tag.root.innerHTML.should.be.equal('Hello there')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/tags/rg-raw/rg-raw.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
--------------------------------------------------------------------------------
/tags/rg-select/rg-select.filter.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-select', function () {
2 | let tag, select
3 | let spyOnOpen = sinon.spy()
4 | let spyOnClose = sinon.spy()
5 | let spyOnSelect = sinon.spy()
6 | let spyOnFilter = sinon.spy()
7 |
8 | beforeEach(function () {
9 | select = {
10 | placeholder: 'Please select a card',
11 | filter: 'text',
12 | options: [{
13 | id: 0,
14 | text: 'Visa'
15 | }, {
16 | id: 1,
17 | text: 'MasterCard'
18 | }, {
19 | id: 2,
20 | text: 'American Express'
21 | }, {
22 | id: 3,
23 | text: 'Discover'
24 | }]
25 | }
26 | $('body').append('')
27 | tag = riot.mount('rg-select', {
28 | select
29 | })[0]
30 | tag.on('open', spyOnOpen)
31 | .on('close', spyOnClose)
32 | .on('select', spyOnSelect)
33 | .on('filter', spyOnFilter)
34 | })
35 |
36 | afterEach(function () {
37 | spyOnOpen.resetHistory()
38 | spyOnClose.resetHistory()
39 | spyOnSelect.resetHistory()
40 |
41 | tag.unmount()
42 | })
43 |
44 | it('is mounted', function () {
45 | tag.isMounted.should.be.true
46 | })
47 |
48 | it ('text input is editable', function () {
49 | should.not.exist($('rg-select .field').attr('readonly'))
50 | })
51 |
52 | it('opens the menu on focus', function () {
53 | $('rg-select .menu').length.should.equal(0)
54 | $('rg-select .field').focus()
55 | $('rg-select .menu').length.should.equal(1)
56 | })
57 |
58 | // skipping because jquery is no triggegin "input" events
59 | it('adding text to box filters the options list', function () {
60 | const field = tag.root.querySelector('.field')
61 | $('rg-select .menu').length.should.equal(0)
62 | field.focus()
63 | $('rg-select .menu').length.should.equal(1)
64 | $('rg-select .menu__item').length.should.equal(4)
65 | spyOnOpen.should.have.been.calledOnce
66 | field.value = 'm'
67 | tag.keydown({ keyCode: 77, preventDefault: () => {} })
68 | tag.update()
69 | spyOnFilter.should.have.been.calledOnce
70 | $('rg-select .menu__item').length.should.equal(2)
71 | })
72 | })
73 |
--------------------------------------------------------------------------------
/tags/rg-select/rg-select.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-select', function () {
2 | let tag, select
3 | let spyOnOpen = sinon.spy()
4 | let spyOnClose = sinon.spy()
5 | let spyOnSelect = sinon.spy()
6 |
7 | beforeEach(function () {
8 | select = {
9 | placeholder: 'Please select a card',
10 | options: [{
11 | id: 0,
12 | text: 'Visa'
13 | }, {
14 | id: 1,
15 | text: 'MasterCard',
16 | selected: true
17 | }, {
18 | id: 2,
19 | text: 'American Express'
20 | }, {
21 | id: 4,
22 | text: 'Disabled Card',
23 | disabled: true,
24 | }, {
25 | id: 3,
26 | text: 'Discover',
27 | }]
28 | }
29 | $('body').append('')
30 | tag = riot.mount('rg-select', {
31 | select
32 | })[0]
33 | tag.on('open', spyOnOpen)
34 | .on('close', spyOnClose)
35 | .on('select', spyOnSelect)
36 | })
37 |
38 | afterEach(function () {
39 | spyOnOpen.resetHistory()
40 | spyOnClose.resetHistory()
41 | spyOnSelect.resetHistory()
42 | tag.unmount()
43 | })
44 |
45 | it('is mounted', function () {
46 | tag.isMounted.should.be.true
47 | })
48 |
49 | it('text input is readonly', function () {
50 | should.exist($('rg-select .field').attr('readonly'))
51 | })
52 |
53 | it('has no items visible on load', function () {
54 | $('rg-select .menu__item').length.should.equal(0)
55 | })
56 |
57 | it('focusing/blurring field opens/closes dropdown and triggers open/close event', function () {
58 | $('rg-select .menu').length.should.equal(0)
59 | tag.root.querySelector('.field').focus()
60 | $('rg-select .menu').length.should.equal(1)
61 | spyOnOpen.should.have.been.calledOnce
62 |
63 | // clicking field doesn't close it
64 | tag.root.querySelector('.field').click()
65 | $('rg-select .menu').length.should.equal(1)
66 |
67 | // clicking outside rg-select does
68 | $('rg-select').parent().click()
69 | $('rg-select .menu').length.should.equal(0)
70 | spyOnClose.should.have.been.calledOnce
71 | })
72 |
73 | it('pressing key down will highlight item', function () {
74 | const field = tag.root.querySelector(".field")
75 | field.focus()
76 | tag.keydown({ keyCode: 38, preventDefault: () => {} })
77 | tag.update()
78 | $('rg-select .menu__item.menu__item--hover').text().should.contain('Discover')
79 | })
80 |
81 | it('selecting an item sets it to selected and calls onselect', function () {
82 | const field = tag.root.querySelector(".field")
83 | field.focus()
84 | $('rg-select .menu__item:nth-child(3)')[0].click()
85 | field.value.should.equal('American Express')
86 | field.blur()
87 | field.focus()
88 | $('rg-select .menu__item:nth-child(3)').is('.menu__item--active').should.be.true
89 | spyOnSelect.should.have.been.calledOnce
90 | })
91 |
92 | it('opens the dropdown on enter', function () {
93 | tag.keydown({ keyCode: 13, preventDefault: () => {} })
94 | tag.update()
95 | $('rg-select .menu').length.should.equal(1)
96 | spyOnOpen.should.have.been.calledOnce
97 | tag.keydown({ keyCode: 13, preventDefault: () => {} })
98 | tag.update()
99 | $('rg-select .menu').length.should.equal(0)
100 | tag.root.querySelector('input').value.should.equal("Visa")
101 | })
102 |
103 | it('opens the dropdown on arrow up', function () {
104 | tag.keydown({ keyCode: 38, preventDefault: () => {} })
105 | tag.update()
106 | $('rg-select .menu').length.should.equal(1)
107 | spyOnOpen.should.have.been.calledOnce
108 | })
109 |
110 | it('opens the dropdown on arrow down', function () {
111 | tag.keydown({ keyCode: 40, preventDefault: () => {} })
112 | tag.update()
113 | $('rg-select .menu').length.should.equal(1)
114 | spyOnOpen.should.have.been.calledOnce
115 | })
116 |
117 | it('does not break on bad navigate', function() {
118 | tag._navigate(99999)
119 | })
120 | })
121 |
--------------------------------------------------------------------------------
/tags/rg-select/rg-select.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
17 |
18 |
118 |
119 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/tags/rg-tabs/rg-tabs.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-tabs', function() {
2 | const default_opts = {
3 | tabs: {
4 | tabs: [{
5 | heading: 'Tab one',
6 | text: 'This is tab one'
7 | }, {
8 | heading: 'Tab two',
9 | text: 'This is tab two',
10 | active: true
11 | }, {
12 | heading: 'Disabled tab',
13 | disabled: true
14 | }, {
15 | heading: 'Tab three',
16 | include: 'yay.html'
17 | }]
18 | }
19 | }
20 |
21 | afterEach(function() {
22 | tag.unmount()
23 | })
24 |
25 | it('is mounted (no opts)', function() {
26 | tag = newTag('rg-tabs')
27 | tag.isMounted.should.be.true
28 | })
29 |
30 | it('has correct number of tabs', function() {
31 | tag = newTag('rg-tabs', default_opts)
32 | $('rg-tabs .tabs__tab').length.should.equal(4)
33 | })
34 |
35 | it('can preset tab as active', function() {
36 | tag = newTag('rg-tabs', default_opts)
37 | $('rg-tabs .tab-heading:nth-child(2)').is('.tab-heading--active').should.be.true
38 | })
39 |
40 | it('can disable tabs', function() {
41 | tag = newTag('rg-tabs', default_opts)
42 | $('rg-tabs .tab-heading:nth-child(3)').is('.tab-heading--disabled').should.be.true
43 | })
44 |
45 | it('heading renders text', function() {
46 | tag = newTag('rg-tabs', default_opts)
47 | $('rg-tabs .tab-heading:nth-child(2)').text().should.contain('Tab two')
48 | $('rg-tabs .tab-heading:nth-child(3)').text().should.contain('Disabled tab')
49 | $('rg-tabs .tab-heading:nth-child(4)').text().should.contain('Tab three')
50 | })
51 |
52 | it('clicking header actives tab', function() {
53 | tag = newTag('rg-tabs', default_opts)
54 | $('rg-tabs .tab-heading:nth-child(4)').click()
55 | $('rg-tabs .tab-heading:nth-child(1)').is('.tab-heading--active').should.be.false
56 | $('rg-tabs .tab-heading:nth-child(2)').is('.tab-heading--active').should.be.false
57 | })
58 |
59 | it('tab is body is rendered', function() {
60 | tag = newTag('rg-tabs', default_opts)
61 | $('rg-tabs .tabs__tab--active').html().should.contain('This is tab two')
62 | })
63 |
64 | it('clicking disabled tab does nothing', function() {
65 | tag = newTag('rg-tabs', default_opts)
66 | $('rg-tabs .tab-heading:nth-child(3)').click()
67 | $('rg-tabs .tab-heading:nth-child(2)').is('.tab-heading--active').should.be.true
68 | })
69 |
70 | it('onopen callback is called on tab click', function() {
71 | tag = newTag('rg-tabs', default_opts)
72 | const spy = sinon.spy()
73 | tag.on('open', spy)
74 | $('rg-tabs .tab-heading:nth-child(1)').click()
75 | spy.should.have.been.called
76 | })
77 |
78 | it('loads content from ajax via opts.tabs.url', function(done) {
79 | mockAjax()
80 | tag = newTag('rg-tabs', default_opts)
81 | $('rg-tabs .tab-heading:nth-child(4)').click()
82 | setTimeout(() => {
83 | tag.root.querySelector(".tabs__tab--active").innerText.should.equal('Yay!')
84 | done()
85 | },0)
86 | unmockAjax()
87 | })
88 | })
89 |
--------------------------------------------------------------------------------
/tags/rg-tabs/rg-tabs.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | { heading }
6 |
7 |
8 |
9 | { text }
10 |
11 |
12 | { include.responseText }
13 |
14 |
15 |
16 |
17 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/tags/rg-tags/rg-tags.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-tags', function () {
2 | let tag, tags
3 | const default_opts = {
4 | tags: {
5 | placeholder: 'Please select a card',
6 | options: [{
7 | id: 0,
8 | text: 'Visa'
9 | }, {
10 | id: 1,
11 | text: 'MasterCard',
12 | selected: true
13 | }, {
14 | id: 2,
15 | text: 'American Express'
16 | }, {
17 | id: 3,
18 | text: 'Discover'
19 | }]
20 | }
21 | }
22 |
23 | afterEach(function () {
24 | tag.unmount()
25 | })
26 |
27 | it('is mounted (no opts)', function () {
28 | tag = newTag('rg-tags')
29 | tag.isMounted.should.be.true
30 | })
31 |
32 | it('is mounted (empty opts.tags)', function () {
33 | tag = newTag('rg-tags', {tags: {}})
34 | tag.isMounted.should.be.true
35 | })
36 |
37 | it('has no items visible on load', function () {
38 | tag = newTag('rg-tags', default_opts)
39 | $('rg-tags .menu__item').length.should.equal(0)
40 | })
41 |
42 | it('loads a tag via opts', function () {
43 | tag = newTag('rg-tags', {tags: { tags: [ { name: 'foo' } ]}})
44 | tag.root.querySelectorAll('.tag').length.should.equal(1)
45 | })
46 |
47 | it('selecting an item calls onselect and resets the menu', function () {
48 | tag = newTag('rg-tags',default_opts)
49 | $('rg-tags .field').focus()
50 | $('rg-tags .menu__item:nth-child(3)').click()
51 | tag.root.querySelectorAll('.tag').length.should.equal(1)
52 | tag.root.querySelector('.button').click()
53 | tag.root.querySelectorAll('.tag').length.should.equal(0)
54 | })
55 |
56 | it('cannot add the same tag twice', function() {
57 | tag = newTag('rg-tags',default_opts)
58 | tag.addTag(default_opts.tags.options[0])
59 | tag.update()
60 | tag.root.querySelectorAll('.tag').length.should.equal(1)
61 | tag.addTag(default_opts.tags.options[0])
62 | tag.update()
63 | tag.root.querySelectorAll('.tag').length.should.equal(1)
64 | tag.addTag(default_opts.tags.options[1])
65 | tag.update()
66 | tag.root.querySelectorAll('.tag').length.should.equal(2)
67 | tag.root.querySelectorAll('.tag')[1].click()
68 | tag.root.querySelectorAll('.tag').length.should.equal(1)
69 | })
70 | })
71 |
--------------------------------------------------------------------------------
/tags/rg-tags/rg-tags.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
50 |
51 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/tags/rg-toast/rg-toasts.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-toast', function () {
2 | let tag, onClickSpy, onCloseSpy, toasts
3 |
4 | beforeEach(function () {
5 | onClickSpy = sinon.spy()
6 | onCloseSpy = sinon.spy()
7 | toasts = {
8 | position: 'bottomleft',
9 | toasts: [{
10 | text: 'Auto disappear',
11 | timeout: 500
12 | }, {
13 | text: 'Auto disappear call onclose',
14 | }, {
15 | text: 'Sticky toast',
16 | sticky: true
17 | }]
18 | }
19 | $('body').append('')
20 | tag = riot.mount('rg-toasts', {
21 | toasts
22 | })[0]
23 | tag.on('select', onClickSpy)
24 | .on('close', onCloseSpy)
25 | })
26 |
27 | afterEach(function () {
28 | tag.unmount()
29 | })
30 |
31 | it('is mounted', function () {
32 | tag.isMounted.should.be.true
33 | })
34 |
35 | it('position can be set', function () {
36 | $('rg-toasts .toasts--bottomleft').length.should.equal(1)
37 | })
38 |
39 | it('has correct number of toasts', function () {
40 | $('rg-toasts .toast').length.should.equal(3)
41 | $('rg-toasts .toast').text().should.contain('Auto disappear')
42 | $('rg-toasts .toast').text().should.contain('Auto disappear call onclose')
43 | $('rg-toasts .toast').text().should.contain('Sticky toast')
44 | })
45 |
46 | it('disappears on click', function () {
47 | $('rg-toasts .toast:first-child').click()
48 | $('rg-toasts .toast').length.should.equal(2)
49 | })
50 |
51 | it('called onclick on click', function () {
52 | $('rg-toasts .toast:nth-child(3)').click()
53 | onClickSpy.should.have.been.called
54 | })
55 | })
56 |
57 | describe('rg-toast no position', function () {
58 | let tag, toasts
59 |
60 | beforeEach(function () {
61 | toasts = {
62 | toasts: [{
63 | text: 'Auto disappear',
64 | timeout: 500
65 | }]
66 | }
67 | $('body').append('')
68 | tag = riot.mount('rg-toasts', {
69 | toasts
70 | })[0]
71 | })
72 |
73 | afterEach(function () {
74 | tag.unmount()
75 | })
76 |
77 | it('is mounted', function () {
78 | tag.isMounted.should.be.true
79 | })
80 |
81 | it('position is defaulted', function () {
82 | $('rg-toasts .toasts--bottomright').length.should.equal(1)
83 | })
84 |
85 | it('loses toast after timeout', function (done) {
86 | tag.root.querySelectorAll('.toast').length.should.equal(1)
87 | setTimeout( () => {
88 | tag.root.querySelectorAll('.toast').length.should.equal(0)
89 | done()
90 | },600)
91 | })
92 | })
93 |
94 | describe('rg-toast no events', function () {
95 | let tag, onClickSpy, onCloseSpy, toasts
96 |
97 | beforeEach(function () {
98 | toasts = {
99 | toasts: [{
100 | text: 'Auto disappear',
101 | timeout: 500
102 | }, {
103 | text: 'Sticky toast',
104 | sticky: true
105 | }]
106 | }
107 | onClickSpy = sinon.spy()
108 | onCloseSpy = sinon.spy()
109 | $('body').append('')
110 | tag = riot.mount('rg-toasts', {
111 | toasts
112 | })[0]
113 | })
114 |
115 | afterEach(function () {
116 | tag.unmount()
117 | })
118 |
119 | it('is mounted', function () {
120 | tag.isMounted.should.be.true
121 | })
122 |
123 | it('onclick and onclose not called on click', function () {
124 | $('rg-toasts .toast:nth-child(3)').click()
125 | onClickSpy.should.not.have.been.called
126 | onCloseSpy.should.not.have.been.called
127 | })
128 |
129 | it('is fine with no opts', function() {
130 | const tag1 = newTag('rg-toasts')
131 | const tag2 = newTag('rg-toasts', {toasts: {toasts: "Bees!"}})
132 | tag1.unmount()
133 | tag2.unmount()
134 | })
135 | })
136 |
--------------------------------------------------------------------------------
/tags/rg-toast/rg-toasts.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/tags/rg-toggle/rg-toggle.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-toggle', function() {
2 | let tag, spy, toggle
3 |
4 | beforeEach(function() {
5 | spy = sinon.spy()
6 | toggle = {
7 | checked: false
8 | }
9 | $('body').append('')
10 | tag = riot.mount('rg-toggle', {
11 | toggle
12 | })[0]
13 | tag.on('toggle', spy)
14 | })
15 |
16 | afterEach(function() {
17 | tag.unmount()
18 | })
19 |
20 | it('is mounted', function() {
21 | tag.isMounted.should.be.true
22 | const tag2 = newTag("rg-toggle")
23 | tag2.isMounted.should.be.true
24 | tag2.unmount()
25 | })
26 |
27 | it('has an unchecked checkbox', function() {
28 | $('rg-toggle input[type=checkbox]').is(':checked').should.be.false
29 | })
30 |
31 | it('has a checked checkbox', function() {
32 | toggle.checked = true
33 | riot.update()
34 | $('rg-toggle input[type=checkbox]').is(':checked').should.be.true
35 | })
36 |
37 | it('calls ontoggle when toggled', function() {
38 | tag.root.querySelector('input').click()
39 | spy.should.have.been.called
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/tags/rg-toggle/rg-toggle.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tags/rg-unsplash/rg-unsplash.spec.js:
--------------------------------------------------------------------------------
1 | describe('rg-unsplash', function() {
2 | let tag
3 |
4 | afterEach(function() {
5 | tag.unmount()
6 | })
7 |
8 | it('is mounted', function() {
9 | tag = newTag('rg-unsplash')
10 | tag.isMounted.should.be.true
11 | })
12 |
13 | it('compiles the correct src with all options', function() {
14 | const unsplash = {}
15 | unsplash.width = 200
16 | unsplash.height = 100
17 | unsplash.greyscale = true
18 | unsplash.random = true
19 | unsplash.blur = true
20 | unsplash.image = '491'
21 | unsplash.gravity = 'north'
22 | tag = newTag('rg-unsplash', { unsplash })
23 | $('rg-unsplash img').length.should.equal(1)
24 | const expected = 'https://unsplash.it/g/200/100/?random&blur&image=491&gravity=north'
25 | $('rg-unsplash img').attr('src').should.equal(expected)
26 | })
27 |
28 | it('compiles the correct src with no options', function() {
29 | tag = newTag('rg-unsplash')
30 | $('rg-unsplash img').attr('src').should.equal('https://unsplash.it/450/250/?')
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/tags/rg-unsplash/rg-unsplash.tag:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test-helpers.js:
--------------------------------------------------------------------------------
1 | const deepClone = obj => {
2 | if(obj===null || typeof obj !== "object"){
3 | return obj;
4 | }
5 |
6 | if(obj instanceof Date){
7 | return new Date(obj.getTime());
8 | }
9 |
10 | if(Array.isArray(obj)){
11 | var clonedArr = [];
12 | obj.forEach(function(element){
13 | clonedArr.push(deepClone(element))
14 | });
15 | return clonedArr;
16 | }
17 |
18 | let clonedObj = new obj.constructor();
19 | for(var prop in obj){
20 | if(obj.hasOwnProperty(prop)){
21 | clonedObj[prop] = deepClone(obj[prop]);
22 | }
23 | }
24 | return clonedObj;
25 | }
26 |
27 | const newTag = (tagName, opts) => {
28 | const element = document.createElement(tagName)
29 | document.body.appendChild(element)
30 | const tag = window.riot.mount(element, deepClone(opts))[0]
31 |
32 | // in anticipation of riot 4
33 | tag.$ = q => tag.root.querySelector(q)
34 | tag.$$ = q => tag.root.querySelectorAll(q)
35 | return tag
36 | }
37 |
38 | const OGXMLHttpRequest = XMLHttpRequest
39 |
40 | const MockXMLHttpRequest = function() {
41 | return {
42 | open(_method, url) {
43 | this.url = url
44 | this.responseText = MockXMLHttpRequest[url]
45 | if (!this.responseText) {
46 | throw `Mocked url response missing for ${url}`
47 | }
48 | },
49 | send() {
50 | this.onload && this.onload(this.responseText)
51 | }
52 | }
53 | }
54 |
55 |
56 | MockXMLHttpRequest['yay.html'] = "Yay!"
57 | MockXMLHttpRequest.is_mock = true
58 |
59 | OGXMLHttpRequest.is_mock = false
60 | const mockAjax = () => {
61 | window.XMLHttpRequest = MockXMLHttpRequest
62 | }
63 |
64 | const unmockAjax = () => {
65 | window.XMLHttpRequest = OGXMLHttpRequest
66 | }
67 |
68 | const mySpy = (tag, events) => {
69 | let last = {}
70 | const spies = {}
71 | events.forEach( e => {
72 | spies[e] = sinon.spy()
73 | tag.on(e, spies[e])
74 | })
75 | const validate = (values) => {
76 | Object.assign(last,values)
77 | events.forEach(e => {
78 | spies[e].callCount.should.equal(last[e] || 0)
79 | })
80 | }
81 | validate.reset = () => {
82 | last = {}
83 | events.forEach(e => spies[e].resetHistory())
84 | }
85 | return validate
86 | }
--------------------------------------------------------------------------------