├── .gitattributes ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── doc ├── 2013_04_30 TNC-CoastalResilience-TechDesign-rev9.pdf ├── arch │ └── adr-001-layer-selector-rewrite.md └── installer_creator.md ├── docker-compose.yml ├── js_requirements.txt ├── mxds └── print_layouts │ ├── Letter ANSI A GeoSiteFramework Landscape Legend.mxd │ ├── Letter ANSI A GeoSiteFramework Landscape.mxd │ ├── Letter ANSI A GeoSiteFramework Portrait Legend.mxd │ ├── Letter ANSI A GeoSiteFramework Portrait.mxd │ └── README.txt ├── scripts ├── __init__.py ├── create_static.py ├── main.py ├── plugin_loader.py ├── py_server.py ├── script_helpers.py ├── server.py └── update.py ├── src ├── App_Data │ ├── pluginSchema.json │ └── regionSchema.json ├── Dockerfile ├── Scripts │ ├── json2.js │ └── json2.min.js ├── Views │ └── Shared │ │ ├── CustomLaunchPadContent.cshtml │ │ ├── SinglePluginModeHelp.cshtml │ │ └── TourInfo.cshtml ├── css │ ├── TinyBox2.css │ ├── app-print.css │ ├── jquery-ui-slider-pips.css │ ├── main.css │ ├── measure.css │ ├── pageguide.min.css │ ├── print-a4-landscape.css │ ├── print-a4-portrait.css │ ├── print-hide-map0.css │ ├── print-hide-map1.css │ ├── print-letter-landscape.css │ ├── print-letter-portrait.css │ ├── print.css │ ├── pushy.css │ ├── single-plugin-mode.css │ └── styleguide.css ├── favicon.ico ├── fonts │ ├── fontello │ │ ├── config.json │ │ ├── css │ │ │ ├── animation.css │ │ │ ├── mantle-codes.css │ │ │ ├── mantle-embedded.css │ │ │ ├── mantle-ie7-codes.css │ │ │ ├── mantle-ie7.css │ │ │ └── mantle.css │ │ └── font │ │ │ ├── mantle.eot │ │ │ ├── mantle.svg │ │ │ ├── mantle.ttf │ │ │ ├── mantle.woff │ │ │ └── mantle.woff2 │ └── opensans │ │ ├── LICENSE.txt │ │ ├── OpenSans-Bold.ttf │ │ └── OpenSans-Regular.ttf ├── img │ ├── Thumbs.db │ ├── favicon.ico │ ├── foundation │ │ └── orbit │ │ │ ├── Thumbs.db │ │ │ ├── bullets.jpg │ │ │ ├── left-arrow-small.png │ │ │ ├── left-arrow.png │ │ │ ├── loading.gif │ │ │ ├── mask-black.png │ │ │ ├── pause-black.png │ │ │ ├── right-arrow-small.png │ │ │ ├── right-arrow.png │ │ │ ├── rotator-black.png │ │ │ └── timer-black.png │ ├── fullMapIcon.svg │ ├── icons │ │ ├── Thumbs.db │ │ ├── icon_close.png │ │ ├── icon_help-support_up.png │ │ ├── icon_link-views_up.png │ │ ├── icon_print_up.png │ │ ├── icon_share_up.png │ │ ├── icon_split_up.png │ │ ├── icon_switch-0_up.png │ │ ├── icon_switch-1_up.png │ │ └── icon_unlink-views_up.png │ ├── infographic-icon.png │ ├── mapLegendIcon.svg │ ├── minMapIcon.svg │ ├── spinner.gif │ └── tlyguide │ │ ├── tlyguide_arrow.png │ │ └── tlyguide_icon.png ├── js │ ├── App.js │ ├── BasemapSelector.js │ ├── Export.js │ ├── Geosite.js │ ├── HelpOverlay.js │ ├── Identify.js │ ├── Legend.js │ ├── Map.js │ ├── MapWrapper.js │ ├── Pane.js │ ├── PausableEvented.js │ ├── Permalink.js │ ├── Plugin.js │ ├── PluginBase.js │ ├── Screen.js │ ├── SidebarToggle.js │ ├── SinglePluginModeHelp.js │ ├── SubRegion.js │ ├── SyncedMapManager.js │ ├── TemplateLoader.js │ ├── TimeoutWrapper.js │ ├── azavea.util.js │ ├── lib │ │ ├── TinyBox2.js │ │ ├── backbone.hashmodels.js │ │ ├── backbone.hashmodels.min.js │ │ ├── backbone.picky.js │ │ ├── backbone.picky.min.js │ │ ├── chosen.jquery.min.js │ │ ├── i18next-2.2.0.min.js │ │ ├── i18next-SprintfPostProcessor-0.2.2.min.js │ │ ├── i18next-XHRBackend-0.3.0.min.js │ │ ├── i18next-jquery-0.0.14.min.js │ │ ├── jquery-ui-slider-pips.min.js │ │ ├── jquery-ui.min.js │ │ ├── jquery.history.min.js │ │ ├── jquery.mousewheel.min.js │ │ ├── jquery.placeholder.js │ │ ├── pageguide.min.js │ │ ├── pushy.js │ │ ├── pushy.min.js │ │ ├── tv4.min.js │ │ ├── underscore.js │ │ └── use.js │ ├── polyfill.js │ ├── tests │ │ └── specRunner.html │ ├── unittest.js │ ├── util │ │ └── ajax.js │ └── widgets │ │ ├── ConstrainedMoveable.js │ │ └── map_utils │ │ ├── export │ │ └── main.js │ │ ├── full_extent │ │ └── main.js │ │ ├── main.js │ │ ├── measure │ │ ├── AgsMeasure.js │ │ └── main.js │ │ └── share │ │ └── main.js ├── locales │ ├── en.json │ └── es.json ├── plugins │ ├── launchpad │ │ ├── icon_sm.png │ │ ├── infographic-icon.png │ │ ├── infographic.html │ │ ├── locales │ │ │ ├── en.json │ │ │ └── es.json │ │ ├── main.js │ │ ├── overrides.json │ │ ├── plugin.json │ │ ├── style.css │ │ └── templates.html │ └── subregion_toggle │ │ ├── icon.png │ │ ├── locales │ │ ├── en.json │ │ └── es.json │ │ ├── main.js │ │ ├── plugin.json │ │ └── subregion-toggle.css ├── region.json ├── requirements.txt ├── sample_plugins │ └── identify_point │ │ ├── FutureHabitat_c.jpg │ │ ├── html │ │ ├── infographic.html │ │ └── print-form.html │ │ ├── icon_sm.png │ │ ├── locales │ │ └── en.json │ │ ├── main.css │ │ ├── main.js │ │ ├── north-arrow.png │ │ ├── plugin.json │ │ ├── print.css │ │ ├── splash.png │ │ ├── template.html │ │ └── tnc-logo.png └── template_index.html ├── styleguide ├── Gruntfile.js ├── LICENSE ├── Readme.md ├── app │ ├── assets │ │ ├── css │ │ │ ├── main.css │ │ │ ├── main.css.map │ │ │ └── styleguide.css │ │ ├── fonts │ │ │ └── fontello │ │ │ │ ├── config.json │ │ │ │ ├── css │ │ │ │ ├── animation.css │ │ │ │ ├── mantle-codes.css │ │ │ │ ├── mantle-embedded.css │ │ │ │ ├── mantle-ie7-codes.css │ │ │ │ ├── mantle-ie7.css │ │ │ │ └── mantle.css │ │ │ │ └── font │ │ │ │ ├── mantle.eot │ │ │ │ ├── mantle.svg │ │ │ │ ├── mantle.ttf │ │ │ │ ├── mantle.woff │ │ │ │ └── mantle.woff2 │ │ ├── images │ │ │ └── .gitkeep │ │ ├── js │ │ │ ├── .gitkeep │ │ │ ├── main.js │ │ │ └── mobileTable.jquery.js │ │ ├── sass │ │ │ ├── _demo.scss │ │ │ ├── base │ │ │ │ ├── .gitkeep │ │ │ │ ├── _base.scss │ │ │ │ └── _normalize.scss │ │ │ ├── components │ │ │ │ ├── .gitkeep │ │ │ │ ├── _alert.scss │ │ │ │ ├── _button.scss │ │ │ │ ├── _dropdown.scss │ │ │ │ ├── _form.scss │ │ │ │ ├── _grid.scss │ │ │ │ ├── _loading.scss │ │ │ │ ├── _map-attribution.scss │ │ │ │ ├── _modal.scss │ │ │ │ ├── _navbar.scss │ │ │ │ ├── _popover.scss │ │ │ │ ├── _sidebar.scss │ │ │ │ ├── _slider.scss │ │ │ │ ├── _table.scss │ │ │ │ ├── _tabs.scss │ │ │ │ └── _tooltip.scss │ │ │ ├── layout │ │ │ │ ├── .gitkeep │ │ │ │ ├── _content.scss │ │ │ │ └── _typography.scss │ │ │ ├── main.scss │ │ │ ├── pages │ │ │ │ └── .gitkeep │ │ │ ├── utils │ │ │ │ ├── .gitkeep │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _functions.scss │ │ │ │ ├── _mixins.scss │ │ │ │ ├── _utilities.scss │ │ │ │ └── _variables.scss │ │ │ └── vendors │ │ │ │ ├── .gitkeep │ │ │ │ └── _snippet_components.scss │ │ └── snippet │ │ │ ├── initialize.js │ │ │ ├── newComponents.css │ │ │ └── style.css │ ├── cr_files │ │ ├── icon_sm(1).png │ │ ├── icon_sm(2).png │ │ ├── icon_sm(3).png │ │ ├── icon_sm(4).png │ │ ├── icon_sm(5).png │ │ ├── icon_sm(6).png │ │ ├── icon_sm.png │ │ └── main.css │ ├── index.html │ └── snippet_index.html ├── grunt │ ├── aliases.yaml │ ├── browserSync.js │ ├── concurrent.js │ ├── postcss.js │ ├── sass.js │ └── watch.js └── package.json ├── testem.json └── tools └── JsTestTools ├── jstdServer.sh ├── jstestdriver ├── JsTestDriver-1.3.1.jar └── why_1.3.1_and_not_1.3.2.txt ├── lib ├── azavea-jasmine │ └── azavea.jasmine.matchers.js ├── jasmine-jquery │ ├── jasmine-jquery-1.2.0.js │ └── source.txt ├── jasmine-jstd-adapter │ ├── JasmineAdapter.js │ └── source.txt ├── jasmine-reporters │ ├── jasmine.console_reporter.js │ ├── jasmine.junit_reporter.js │ └── source.txt ├── jasmine │ ├── MIT.LICENSE │ ├── jasmine-html.js │ ├── jasmine.css │ ├── jasmine.js │ └── source.txt ├── jquery │ └── jquery-1.6.1.min.js └── templates │ ├── jsTestDriver.conf.template │ └── specRunner.html.template ├── phantomjs-testrunner.js ├── phantomjs ├── .gitignore ├── ChangeLog ├── LICENSE.BSD ├── README.md ├── examples │ ├── arguments.coffee │ ├── arguments.js │ ├── colorwheel.coffee │ ├── colorwheel.js │ ├── countdown.coffee │ ├── countdown.js │ ├── cycle_multiple_urls.js │ ├── direction.coffee │ ├── direction.js │ ├── extract-text.coffee │ ├── extract-text.js │ ├── fibo.coffee │ ├── fibo.js │ ├── follow.coffee │ ├── follow.js │ ├── hello.coffee │ ├── hello.js │ ├── ipgeocode.coffee │ ├── ipgeocode.js │ ├── loadspeed.coffee │ ├── loadspeed.js │ ├── movies.coffee │ ├── movies.js │ ├── pizza.coffee │ ├── pizza.js │ ├── rasterize.coffee │ ├── rasterize.js │ ├── run-jasmine.js │ ├── run-qunit.js │ ├── seasonfood.coffee │ ├── seasonfood.js │ ├── technews.coffee │ ├── technews.js │ ├── tweets.coffee │ ├── tweets.js │ ├── useragent.coffee │ ├── useragent.js │ ├── version.coffee │ ├── version.js │ ├── waitfor.coffee │ ├── waitfor.js │ ├── weather.coffee │ └── weather.js ├── phantomjs.pro ├── python │ ├── INSTALL │ ├── LICENSE │ ├── README │ ├── csconverter.py │ ├── networkaccessmanager.py │ ├── phantom.py │ ├── plugincontroller.py │ ├── plugins │ │ ├── __init__.py │ │ └── saveToFile │ │ │ ├── __init__.py │ │ │ └── saveToFile.py │ ├── pyphantomjs.py │ ├── resources.py │ ├── resources.qrc │ ├── resources │ │ ├── coffee-script.js │ │ ├── pyphantomjs-icon.ico │ │ └── pyphantomjs-icon.png │ ├── tools │ │ ├── build_resources.sh │ │ └── setup.py │ ├── utils.py │ └── webpage.py └── src │ ├── coffee-script.js │ ├── consts.h │ ├── csconverter.cpp │ ├── csconverter.h │ ├── gif │ ├── config.h │ ├── egif_lib.c │ ├── gif.pri │ ├── gif_err.c │ ├── gif_hash.c │ ├── gif_hash.h │ ├── gif_lib.h │ ├── gif_lib_private.h │ ├── gifalloc.c │ ├── gifwriter.cpp │ ├── gifwriter.h │ └── quantize.c │ ├── main.cpp │ ├── networkaccessmanager.cpp │ ├── networkaccessmanager.h │ ├── phantom.cpp │ ├── phantom.h │ ├── phantomjs-icon.png │ ├── phantomjs.pro │ ├── phantomjs.qrc │ ├── phantomjs_os2.ico │ ├── phantomjs_os2.rc │ ├── phantomjs_win.ico │ ├── phantomjs_win.rc │ ├── usage.txt │ ├── utils.cpp │ ├── utils.h │ ├── webpage.cpp │ └── webpage.h ├── readme.md ├── runJstd ├── runJstd.bat ├── runJstd.py ├── runPhantom ├── runPhantom.bat └── runPhantom.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # default behavior 2 | * text=auto 3 | 4 | # Force text 5 | *.cs text 6 | *.cshtml text 7 | 8 | # Force CRLF 9 | *.sln text eol=crlf 10 | 11 | # Prevent conversion 12 | *.exe binary 13 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | Brief description of what this PR does, and why it is needed. 4 | 5 | Connects #XXX 6 | 7 | ### Demo 8 | 9 | Optional. Screenshots, `curl` examples, etc. 10 | 11 | ### Notes 12 | 13 | Optional. Ancillary topics, caveats, alternative strategies that didn't work out, anything else. 14 | 15 | ## Testing Instructions 16 | 17 | * How to test this PR 18 | * Prefer bulleted description 19 | * Start after checking out this branch 20 | * Include any setup required, such as bundling scripts, restarting services, etc. 21 | * Include test case, and expected output 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Visual Studio left-overs 4 | *.suo # 'user' settings like 'which file is open in Visual Studio' 5 | *.v11.suo 6 | *.ncb # Used for debugging 7 | *.user 8 | *.ccscc # Used for versioning 9 | *.cache 10 | 11 | # Editor left-overs 12 | *~ # (x)emacs 13 | *.bak # Windows related 14 | \#*\# # (x)emacs 15 | 16 | # Compiled files 17 | src/index.html 18 | 19 | # NuGet 20 | packages 21 | 22 | # NUnit 23 | *.mdf 24 | *.ldf 25 | 26 | # OS left-overs 27 | Thumbs.db # Having images in the source tree generates those files in Explorer 28 | .DS_Store 29 | 30 | # App folders 31 | src/logs 32 | src/languages 33 | 34 | # Python 35 | *.pyc 36 | *__pycache__/ 37 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 3.0.3 2 | 3 | - Fixed a bug that provided the wrong API key to Google Analytics. 4 | 5 | 3.0.2 6 | 7 | - Fixed an issue that prevented events being assigned to plugins in single plugin mode in certain cases. 8 | 9 | 3.0.1 10 | 11 | - Add support for story mode to region.json schema 12 | 13 | 3.0.0 14 | 15 | - Initial release of static site 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GeositeFramework 2 | ================ 3 | A Javascript framework for hosting map tool plugins. Developed to support the [Coastal Resilience](http://coastalresilience.org/) suite of [tools](http://maps.coastalresilience.org/network/). 4 | 5 | Coastal Resilience is a program of The Nature Conservancy that supports a community of practitioners around the world who are applying planning innovations, the web-based mapping tool framework and individual Coastal Resilience “apps” or plugins to the framework to coastal hazards and adaptation issues. 6 | 7 | Copyright (C) 2019 The Nature Conservancy 8 | 9 | ### Developing 10 | To run the project locally, on any OS, clone the repo and ensure you have `Python 2.x`. You can choose to work on your host machine or within a docker container. It is advised to work within docker if you'd rather not adjust your local python setup. 11 | 12 | #### Running the development environment on your host 13 | Ensure `pip` is installed. 14 | 15 | Install the python requirements: 16 | ``` 17 | python ./scripts/update.py 18 | ``` 19 | 20 | Run the development server and serve the static assets: 21 | ``` 22 | python ./scripts/server.py 23 | ``` 24 | 25 | #### Running the development environment through Docker 26 | Ensure [`docker`](https://www.docker.com/) and `docker-compose` are installed and that the docker client is running. 27 | 28 | The same commands as above will run within docker if passed a docker flag, `-d`: 29 | 30 | Build the docker container with dependencies installed and serve the static assets: 31 | ``` 32 | python ./scripts/server.py -d 33 | ``` 34 | 35 | If requirements should change, dependencies can be updated via script: 36 | ``` 37 | python ./scripts/update.py -d 38 | ``` 39 | 40 | Containers can be accessed by bash in the usual way: 41 | ``` 42 | docker-compose exec /bin/bash 43 | ``` 44 | 45 | To stop the docker server: 46 | ``` 47 | docker-compose stop server 48 | ``` 49 | 50 | #### Ports 51 | 52 | | Service | Port | 53 | | ------------------ | --------------------------------- | 54 | | Python Dev Server | [`54634`](http://localhost:54634) | 55 | 56 | #### Scripts 57 | 58 | Prefix script calls with `python`, if python is not in your `$PATH`. 59 | 60 | | Name | Description | 61 | | ------------------ | ------------------------------------------------------------- | 62 | | `server.py` | Run a Python SimpleHTTPServer serving the templated app | 63 | | `update.py` | Install python dependencies | 64 | | `create_static.py` | Write and compile static assets directly | 65 | -------------------------------------------------------------------------------- /doc/2013_04_30 TNC-CoastalResilience-TechDesign-rev9.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/doc/2013_04_30 TNC-CoastalResilience-TechDesign-rev9.pdf -------------------------------------------------------------------------------- /doc/arch/adr-001-layer-selector-rewrite.md: -------------------------------------------------------------------------------- 1 | # Layer Selector Rewrite 2 | 3 | ## Context 4 | 5 | The layer selector plugin has grown in complexity over the years and has 6 | accumulated a fair amount of technical debt. Fixing bugs and adding new 7 | features has become increasingly difficult and time consuming as a result. 8 | 9 | Some issues with the current implementation: 10 | 11 | * The widget we use ([Ext JS Tree Panel](https://docs.sencha.com/extjs/6.0/components/trees.html)) 12 | does not provide enough control over how nodes are rendered. 13 | * It is difficult to add buttons and other interactions to each leaf node 14 | (zoom to extent, download button, etc.) using Ext JS Tree Panel. 15 | * Separation between *saved state* and *actual state*. The in-memory representation 16 | of the tree often differs from the serialized tree state, which has led to 17 | synchronization issues. 18 | * Lack of high-level data abstractions make it difficult to understand 19 | how the plugin transforms data for rendering. 20 | * Mutable state occasionally leads to data corruption caused by performing 21 | certain sequences. 22 | 23 | ## Decision 24 | 25 | We have decided to rewrite the layer selector from scratch before adding 26 | new features. 27 | 28 | To resolve the problems previously described, the new layer selector should 29 | have the following qualities: 30 | 31 | * The UI should be defined using simple `underscore` templates so we retain 32 | full control over the look & feel. 33 | * All user interactions should aspire to update a singular state object, 34 | which will then cause the UI to be redrawn. In this way, the UI will always 35 | be a reflection of what actually exists in the saved state. 36 | * There should be a separation between the layer config and the layer data 37 | that is loaded at runtime. This is to prevent bugs that can result from 38 | mutating a single state repeatedly. 39 | * Services and layer data should be lazily loaded when possible. 40 | 41 | ## Consequences 42 | 43 | Some of these consequences will be resolved after the initial rewrite has been 44 | completed. 45 | 46 | * There will be less configuration options. 47 | * Subregions won't be supported. 48 | * Service params will not be supported (displayLevels, mode, symbology, autoGeneralize, displayOnPan, etc.) 49 | * Changes to `layers.json` schema will not be backwards compatible (Ref: https://gist.github.com/caseypt/afb0d266f3144af212d0). -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | server: 4 | build: 5 | context: ./src/ 6 | working_dir: /usr/src/ 7 | ports: 8 | - "54634:54634" 9 | volumes: 10 | - ./src:/usr/src/src/ 11 | - ./scripts:/usr/src/scripts 12 | - ./dist:/usr/dist 13 | -------------------------------------------------------------------------------- /mxds/print_layouts/Letter ANSI A GeoSiteFramework Landscape Legend.mxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/mxds/print_layouts/Letter ANSI A GeoSiteFramework Landscape Legend.mxd -------------------------------------------------------------------------------- /mxds/print_layouts/Letter ANSI A GeoSiteFramework Landscape.mxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/mxds/print_layouts/Letter ANSI A GeoSiteFramework Landscape.mxd -------------------------------------------------------------------------------- /mxds/print_layouts/Letter ANSI A GeoSiteFramework Portrait Legend.mxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/mxds/print_layouts/Letter ANSI A GeoSiteFramework Portrait Legend.mxd -------------------------------------------------------------------------------- /mxds/print_layouts/Letter ANSI A GeoSiteFramework Portrait.mxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/mxds/print_layouts/Letter ANSI A GeoSiteFramework Portrait.mxd -------------------------------------------------------------------------------- /mxds/print_layouts/README.txt: -------------------------------------------------------------------------------- 1 | These custom templates can be installed on the print server specified in the region.json config file, in the ExportWebMapTemplates directory of the ArcGIS installation. You must restart the PrintTask service after changing the contents of that directory, since the template names are cached. -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/scripts/__init__.py -------------------------------------------------------------------------------- /scripts/create_static.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Compile static assets via script 5 | 6 | Usage: python ./scripts/create_static.py [OPTIONS] 7 | 8 | """ 9 | 10 | import argparse 11 | import sys 12 | import subprocess 13 | import logging 14 | 15 | logging.basicConfig(level=logging.INFO) 16 | 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument('-d', 19 | help='Run from within python docker container.', 20 | action='store_true') 21 | args = parser.parse_args() 22 | 23 | logging.info('Attempting to compile static assets...') 24 | 25 | if args.d: 26 | command = ('docker-compose run --rm server ./scripts/main.py') 27 | return_value = subprocess.call(command, stderr=subprocess.STDOUT, 28 | shell=True) 29 | else: 30 | command = ('./scripts/main.py') 31 | return_value = subprocess.call(command, stderr=subprocess.STDOUT, 32 | shell=True) 33 | 34 | if return_value != 0: 35 | logging.error('Exiting before compiling static assets.') 36 | sys.exit() 37 | 38 | logging.info('Finished compiling static assets.') 39 | -------------------------------------------------------------------------------- /scripts/py_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import logging 5 | from BaseHTTPServer import HTTPServer 6 | from SimpleHTTPServer import SimpleHTTPRequestHandler 7 | import main 8 | 9 | PORT = 54634 10 | PATH_TO_PROJECT = 'src/' 11 | 12 | logging.basicConfig(level=logging.INFO) 13 | 14 | 15 | class CustomRootHTTPServer(HTTPServer): 16 | def __init__(self, base_path, *args, **kwargs): 17 | HTTPServer.__init__(self, *args, **kwargs) 18 | self.RequestHandlerClass.base_path = base_path 19 | 20 | 21 | class CustomRootHTTPRequestHandler(SimpleHTTPRequestHandler): 22 | def translate_path(self, path): 23 | """Serve files from a specific directory.""" 24 | words = filter(None, path.split('/')) 25 | modified_path = self.base_path 26 | for word in words: 27 | modified_path = os.path.join(modified_path, word) 28 | return modified_path 29 | 30 | def do_GET(self): 31 | main.template_index() # create template files 32 | 33 | return SimpleHTTPRequestHandler.do_GET(self) 34 | 35 | 36 | def serve(): 37 | server = CustomRootHTTPServer(PATH_TO_PROJECT, ('', PORT), 38 | CustomRootHTTPRequestHandler) 39 | logging.info('Now serving on http://localhost:%s' % PORT) 40 | server.serve_forever() 41 | 42 | 43 | if __name__ == '__main__': 44 | serve() 45 | -------------------------------------------------------------------------------- /scripts/script_helpers.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | BASE_DIR = 'src' 5 | REGION_FILE = os.path.join(BASE_DIR, 'region.json') 6 | 7 | 8 | def to_json(file): 9 | """Opens a JSON file and converts it to JSON""" 10 | with open(file) as f: 11 | return json.load(f) 12 | 13 | 14 | def extract_filepaths_from_dirs(directory_list): 15 | """Returns the full paths of all files in a list of directories""" 16 | f = [] 17 | for dir in directory_list: 18 | f.append([os.path.join(dir, file) 19 | for (path, dirs, files) in os.walk(dir) 20 | for file in files]) 21 | return f 22 | -------------------------------------------------------------------------------- /scripts/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Static site server script 5 | 6 | Usage: python ./scripts/server.py [OPTIONS] 7 | 8 | """ 9 | import argparse 10 | import subprocess 11 | import py_server 12 | import signal 13 | 14 | 15 | def handler(signum, frame): 16 | subprocess.call('docker-compose stop server', shell=True) 17 | 18 | 19 | if __name__ == '__main__': 20 | parser = argparse.ArgumentParser() 21 | parser.add_argument('-d', 22 | help='Start server within a python docker container.', 23 | action='store_true') 24 | args = parser.parse_args() 25 | 26 | if args.d: 27 | subprocess.call('docker-compose -f docker-compose.yml up', 28 | shell=True) 29 | # kill docker container when script is stopped 30 | signal.signal(signal.SIGINT, handler) 31 | else: 32 | py_server.serve() 33 | -------------------------------------------------------------------------------- /scripts/update.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Update python dependencies via script 5 | 6 | Usage: python ./scripts/update.py [OPTIONS] 7 | """ 8 | import argparse 9 | import subprocess 10 | import logging 11 | 12 | logging.basicConfig(level=logging.INFO) 13 | 14 | parser = argparse.ArgumentParser() 15 | parser.add_argument('-d', 16 | help='Update dependencies within ' + 17 | 'the python docker container.', 18 | action='store_true') 19 | args = parser.parse_args() 20 | 21 | logging.info('Updating python dependencies...') 22 | if args.d: 23 | subprocess.call('docker-compose build', shell=True) 24 | else: 25 | subprocess.call('pip install -r src/requirements.txt', 26 | shell=True) 27 | -------------------------------------------------------------------------------- /src/App_Data/pluginSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-03/schema#", 3 | "title": "Geosite plugin configuration", 4 | "type": "object", 5 | "properties": { 6 | "css": { 7 | "type": "array", 8 | "items": {"type": "string"} 9 | }, 10 | "use": {"type": "object"} 11 | }, 12 | "additionalProperties": false 13 | } 14 | -------------------------------------------------------------------------------- /src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7-slim 2 | 3 | WORKDIR /usr/src/ 4 | 5 | COPY requirements.txt . 6 | 7 | RUN pip install -r requirements.txt 8 | 9 | ENTRYPOINT ["python"] 10 | 11 | CMD ["./scripts/py_server.py"] 12 | -------------------------------------------------------------------------------- /src/Scripts/json2.min.js: -------------------------------------------------------------------------------- 1 | var JSON;JSON||(JSON={}),(function(){"use strict";function i(n){return n<10?"0"+n:n}function f(n){return o.lastIndex=0,o.test(n)?'"'+n.replace(o,function(n){var t=s[n];return typeof t=="string"?t:"\\u"+("0000"+n.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+n+'"'}function r(i,e){var h,l,c,a,v=n,s,o=e[i];o&&typeof o=="object"&&typeof o.toJSON=="function"&&(o=o.toJSON(i)),typeof t=="function"&&(o=t.call(e,i,o));switch(typeof o){case"string":return f(o);case"number":return isFinite(o)?String(o):"null";case"boolean":case"null":return String(o);case"object":if(!o)return"null";n+=u,s=[];if(Object.prototype.toString.apply(o)==="[object Array]"){for(a=o.length,h=0;hCustom Launchpad 2 |
3 | This shows how it is possible to include custom launchpad markup. 4 |
5 | 6 | -------------------------------------------------------------------------------- /src/Views/Shared/SinglePluginModeHelp.cshtml: -------------------------------------------------------------------------------- 1 | 2 |
3 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum 4 |
5 | -------------------------------------------------------------------------------- /src/css/TinyBox2.css: -------------------------------------------------------------------------------- 1 | .tmask { 2 | position: absolute; 3 | display: none; 4 | top: 0px; 5 | left: 0px; 6 | height: 100%; 7 | width: 100%; 8 | background: #000; 9 | z-index: 800; 10 | } 11 | .tbox { 12 | position: absolute; 13 | display: none; 14 | padding: 14px 17px; 15 | z-index: 900; 16 | } 17 | 18 | .tclose { 19 | position: absolute; 20 | top: 0px; 21 | right: 0px; 22 | width: 30px; 23 | height: 30px; 24 | cursor: pointer; 25 | background: url(../img/icons/icon_close.png) no-repeat; 26 | } 27 | .tclose:hover { 28 | background-position:0 -30px; 29 | } 30 | .tinner { 31 | padding: 15px; 32 | border-radius: 5px; 33 | background: #fff; 34 | border-right: 1px solid #333; 35 | border-bottom: 1px solid #333; 36 | position: relative; 37 | } 38 | 39 | /* CSS helper classes for responsive plugins to use TINY box */ 40 | 41 | #plugin-tiny-box { 42 | border-radius: 0px !important; 43 | } 44 | 45 | .tinner .plugin-tiny-box-header { 46 | padding: 10px 16px; 47 | } 48 | 49 | .tinner .plugin-tiny-box-header .plugin-tiny-box-icon { 50 | margin-right: 5px; 51 | display: inline-block; 52 | vertical-align: middle; 53 | width: 50px; 54 | height: 50px; 55 | } 56 | 57 | .tinner .plugin-tiny-box-header .plugin-tiny-box-title { 58 | font-family: OpenSansBold, colfax, -apple-system, BlinkMacSystemFont, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Arial, sans-serif; 59 | font-size: 16px; 60 | display: inline-block; 61 | color: #000; 62 | margin-top: 10px; 63 | } 64 | 65 | .tinner .tclose { 66 | color: #000 !important; 67 | right: 40px; 68 | font-size: 20px; 69 | top: 20px; 70 | } 71 | 72 | .tinner .tclose:hover { 73 | color: #000 !important; 74 | background: none; 75 | } 76 | 77 | #plugin-tiny-box .tcontent { 78 | overflow: scroll; 79 | } 80 | 81 | @media screen and (max-width: 740px) { 82 | .tinner { 83 | width: calc(100vw + 1px) !important; 84 | height: 100vh !important; 85 | position: relative; 86 | border-radius: 0px !important; 87 | } 88 | 89 | body .tbox { 90 | width: calc(100vw + 1px) !important; 91 | height: 100vh !important; 92 | top: 56px !important; 93 | left: 0px !important; 94 | padding: 0px !important; 95 | } 96 | 97 | .tinner .tclose { 98 | color: #000 !important; 99 | right: 30px; 100 | font-size: 20px; 101 | top: 20px; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/css/app-print.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | .dojoxResizeHandle { 3 | visibility: hidden; 4 | } 5 | 6 | #left-pane { 7 | display: none; 8 | } 9 | 10 | /* !important required to override inline styles, otherwise 11 | print modal appears on top of printed element */ 12 | .tbox { 13 | display: none !important; 14 | } 15 | 16 | .tmask { 17 | display: none !important; 18 | } 19 | 20 | header { 21 | display: none; 22 | } 23 | 24 | #print-map-container > #export-print-preview-map.div.control-container { 25 | display: none; 26 | } 27 | 28 | #print-map-container > #export-print-preview-map > #map-0 > #map-0_root img.layerTile { 29 | visibility: visible; 30 | } 31 | 32 | #print-map-container > #export-print-preview-map > #map-0 > #map-0_root > #map-0_zoom_slider { 33 | display: none; 34 | } 35 | 36 | .plugin-launcher { 37 | display: none; 38 | } 39 | 40 | .legend-close { 41 | visibility: hidden; 42 | } 43 | 44 | #legend-container-0 .dojoxResizeHandle { 45 | display: none; 46 | } 47 | } 48 | 49 | #export-print-preview-container.tinner > div.tcontent { 50 | max-height: 100%; 51 | } 52 | 53 | #export-print-preview-container.tinner > div.tcontent > div.popover { 54 | max-height: 100%; 55 | } 56 | 57 | #export-print-preview-container.tinner > div.tcontent > div.popover > div.popover-content { 58 | max-height: 95%; 59 | height: 95%; 60 | padding-bottom: 5px; 61 | padding-top: 10px; 62 | } 63 | 64 | #export-print-preview-map.div.control-container { 65 | display: none; 66 | } 67 | 68 | .instructions { 69 | display: none; 70 | } 71 | 72 | .legend-close { 73 | visibility: hidden; 74 | } 75 | 76 | #export-title { 77 | width: 100%; 78 | } 79 | .print-sandbox-header .hdr-container { 80 | position: fixed; 81 | height: 0.85in; 82 | text-align: center; 83 | padding-left: 160px; 84 | display: flex; 85 | flex-direction: row; 86 | } 87 | 88 | .print-sandbox-header h1 { 89 | width: 100%; 90 | padding-top: 0.3in; 91 | text-align: center; 92 | } 93 | 94 | .print-sandbox-header { 95 | display: flex; 96 | flex-direction: row; 97 | height: 0.95in; 98 | visibility: visible; 99 | } 100 | -------------------------------------------------------------------------------- /src/css/measure.css: -------------------------------------------------------------------------------- 1 | .measure-info-window .btn.btn-danger { 2 | color: #fff; 3 | background-color: #c9302c; 4 | padding: 5px; 5 | border-width: 0; 6 | border-radius: 2px; 7 | } 8 | .measure-tooltip { 9 | background-color: white; 10 | border: 1px solid #7EABCD; 11 | border-radius: 4px; 12 | padding: 5px; 13 | position: absolute; 14 | width: 200px; 15 | z-index: 9999; 16 | font-family: 'Archivo Narrow', 'Arial Narrow', Arial, Helvetica, sans-serif; 17 | color: #73787d; 18 | } 19 | .measure-tooltip > div { 20 | padding: 5px; 21 | } 22 | .measure-tooltip .measure-label, .measure-bubble .measure-label { 23 | font-weight: bold; 24 | } 25 | 26 | 27 | .content .map .measure { 28 | background-image: url(icon.png); 29 | } 30 | .content .map .active .measure { 31 | background-image: url(icon-active.png); 32 | } 33 | 34 | 35 | /* Fix conflict between our "content" class and esri InfoWindow's "content" class */ 36 | 37 | .infowindow.measure-info-window .content { 38 | display: block; 39 | width: 100%; 40 | overflow: visible; 41 | } 42 | .infowindow.measure-info-window .close { 43 | display: none; 44 | } 45 | 46 | .infowindow.measure-info-window .border { 47 | display: none; 48 | } 49 | 50 | .infowindow.measure-info-window .window { 51 | top: 0 !important; 52 | left: 0 !important; 53 | } 54 | 55 | .infowindow.measure-info-window .layout.content{ 56 | background-color: #fff; 57 | color: #212323; 58 | width: 230px; 59 | height: 60px; 60 | border: 1px solid #7EABCD; 61 | box-shadow: 0 0 15px #666; 62 | box-shadow: 0 0 15px rgba(0,0,0,.5); 63 | border-radius: 4px; 64 | padding: 6px 10px; 65 | font-family: 'Archivo Narrow', 'Arial Narrow', Arial, Helvetica, sans-serif; 66 | line-height: 18px; 67 | } 68 | 69 | .measure-bubble p { 70 | margin-bottom: 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/css/print-hide-map0.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | /* For split screen print, only 1 plugin from one map should be enabled. This hides 3 | any active from map-0 which uses the same print style and lets map-1 plugins show. */ 4 | #map-0, #left-pane { 5 | display: none; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/css/print-hide-map1.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | /* For split screen print, only 1 plugin from one map should be enabled. This hides 3 | any active from map-1 which uses the same print style and lets map-0 plugins show. */ 4 | #map-1, #right-pane { 5 | display: none; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/css/print.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | #map-print-sandbox { 3 | visibility: visible !important; 4 | } 5 | .print-sandbox-header { 6 | display: none !important; 7 | } 8 | /* Hide all body map elements */ 9 | body { 10 | visibility: hidden; 11 | } 12 | 13 | html, body { 14 | overflow: visible !important; 15 | height: auto !important; 16 | } 17 | 18 | /* An issue in Chrome for Windows would display the borders of this 19 | element in print media, despite it being selected by the clause above.*/ 20 | .plugin-launcher { 21 | display: none; 22 | } 23 | 24 | /* Plugin print will only be one side of a split view map ever, so 25 | allow that side to take up the entire width of the screen */ 26 | body.view-split .content { 27 | width: 100%; 28 | } 29 | 30 | #plugin-print-sandbox { 31 | visibility: visible; 32 | height: 90%; 33 | width: 90%; 34 | } 35 | 36 | #plugin-print-sandbox .control-container { 37 | display: none; 38 | } 39 | 40 | .esriSimpleSlider { 41 | display: none; 42 | } 43 | 44 | /* Default styling for map print out */ 45 | #plugin-print-sandbox #legend-container-0 { 46 | float: right; 47 | } 48 | 49 | #plugin-print-sandbox #map-0_root { 50 | float: left; 51 | } 52 | 53 | #print-map-container { 54 | border: none; 55 | } 56 | 57 | .legend-close { 58 | visibility: hidden; 59 | } 60 | 61 | #legend-container-0 .dojoxResizeHandle { 62 | visibility: hidden; 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/favicon.ico -------------------------------------------------------------------------------- /src/fonts/fontello/css/animation.css: -------------------------------------------------------------------------------- 1 | /* 2 | Animation example, for spinners 3 | */ 4 | .animate-spin { 5 | -moz-animation: spin 2s infinite linear; 6 | -o-animation: spin 2s infinite linear; 7 | -webkit-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | display: inline-block; 10 | } 11 | @-moz-keyframes spin { 12 | 0% { 13 | -moz-transform: rotate(0deg); 14 | -o-transform: rotate(0deg); 15 | -webkit-transform: rotate(0deg); 16 | transform: rotate(0deg); 17 | } 18 | 19 | 100% { 20 | -moz-transform: rotate(359deg); 21 | -o-transform: rotate(359deg); 22 | -webkit-transform: rotate(359deg); 23 | transform: rotate(359deg); 24 | } 25 | } 26 | @-webkit-keyframes spin { 27 | 0% { 28 | -moz-transform: rotate(0deg); 29 | -o-transform: rotate(0deg); 30 | -webkit-transform: rotate(0deg); 31 | transform: rotate(0deg); 32 | } 33 | 34 | 100% { 35 | -moz-transform: rotate(359deg); 36 | -o-transform: rotate(359deg); 37 | -webkit-transform: rotate(359deg); 38 | transform: rotate(359deg); 39 | } 40 | } 41 | @-o-keyframes spin { 42 | 0% { 43 | -moz-transform: rotate(0deg); 44 | -o-transform: rotate(0deg); 45 | -webkit-transform: rotate(0deg); 46 | transform: rotate(0deg); 47 | } 48 | 49 | 100% { 50 | -moz-transform: rotate(359deg); 51 | -o-transform: rotate(359deg); 52 | -webkit-transform: rotate(359deg); 53 | transform: rotate(359deg); 54 | } 55 | } 56 | @-ms-keyframes spin { 57 | 0% { 58 | -moz-transform: rotate(0deg); 59 | -o-transform: rotate(0deg); 60 | -webkit-transform: rotate(0deg); 61 | transform: rotate(0deg); 62 | } 63 | 64 | 100% { 65 | -moz-transform: rotate(359deg); 66 | -o-transform: rotate(359deg); 67 | -webkit-transform: rotate(359deg); 68 | transform: rotate(359deg); 69 | } 70 | } 71 | @keyframes spin { 72 | 0% { 73 | -moz-transform: rotate(0deg); 74 | -o-transform: rotate(0deg); 75 | -webkit-transform: rotate(0deg); 76 | transform: rotate(0deg); 77 | } 78 | 79 | 100% { 80 | -moz-transform: rotate(359deg); 81 | -o-transform: rotate(359deg); 82 | -webkit-transform: rotate(359deg); 83 | transform: rotate(359deg); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/fonts/fontello/font/mantle.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/fontello/font/mantle.eot -------------------------------------------------------------------------------- /src/fonts/fontello/font/mantle.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/fontello/font/mantle.ttf -------------------------------------------------------------------------------- /src/fonts/fontello/font/mantle.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/fontello/font/mantle.woff -------------------------------------------------------------------------------- /src/fonts/fontello/font/mantle.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/fontello/font/mantle.woff2 -------------------------------------------------------------------------------- /src/fonts/opensans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/opensans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /src/fonts/opensans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/fonts/opensans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /src/img/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/Thumbs.db -------------------------------------------------------------------------------- /src/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/favicon.ico -------------------------------------------------------------------------------- /src/img/foundation/orbit/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/Thumbs.db -------------------------------------------------------------------------------- /src/img/foundation/orbit/bullets.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/bullets.jpg -------------------------------------------------------------------------------- /src/img/foundation/orbit/left-arrow-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/left-arrow-small.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/left-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/left-arrow.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/loading.gif -------------------------------------------------------------------------------- /src/img/foundation/orbit/mask-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/mask-black.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/pause-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/pause-black.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/right-arrow-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/right-arrow-small.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/right-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/right-arrow.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/rotator-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/rotator-black.png -------------------------------------------------------------------------------- /src/img/foundation/orbit/timer-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/foundation/orbit/timer-black.png -------------------------------------------------------------------------------- /src/img/fullMapIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/img/icons/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/Thumbs.db -------------------------------------------------------------------------------- /src/img/icons/icon_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_close.png -------------------------------------------------------------------------------- /src/img/icons/icon_help-support_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_help-support_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_link-views_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_link-views_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_print_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_print_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_share_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_share_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_split_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_split_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_switch-0_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_switch-0_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_switch-1_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_switch-1_up.png -------------------------------------------------------------------------------- /src/img/icons/icon_unlink-views_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/icons/icon_unlink-views_up.png -------------------------------------------------------------------------------- /src/img/infographic-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/infographic-icon.png -------------------------------------------------------------------------------- /src/img/mapLegendIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 6 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/img/minMapIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/spinner.gif -------------------------------------------------------------------------------- /src/img/tlyguide/tlyguide_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/tlyguide/tlyguide_arrow.png -------------------------------------------------------------------------------- /src/img/tlyguide/tlyguide_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/img/tlyguide/tlyguide_icon.png -------------------------------------------------------------------------------- /src/js/Geosite.js: -------------------------------------------------------------------------------- 1 | //= require jquery 2 | //= require underscore 3 | //= require backbone 4 | 5 | /*jslint nomen: true, browser: true, devel:true*/ 6 | /*global Backbone, _, Geosite*/ 7 | 8 | (function (N) { 9 | "use strict"; 10 | 11 | if (N.Geosite) { 12 | return; 13 | } 14 | 15 | N.Geosite = _.clone(Backbone.Events); 16 | 17 | // Class objects (see App.js for instances) 18 | N.Geosite.models = {}; 19 | N.Geosite.collections = {}; 20 | N.Geosite.views = {}; 21 | N.Geosite.controllers = {}; 22 | N.Geosite.plugins = []; 23 | 24 | N.Geosite.on('error', function handleError(model, error) { 25 | console.log("Geosite error: " + error); 26 | }); 27 | }(this)); 28 | -------------------------------------------------------------------------------- /src/js/HelpOverlay.js: -------------------------------------------------------------------------------- 1 | (function(N) { 2 | 3 | N.controllers.HelpOverlay = function(options) { 4 | this.defaults = _.extend({ 5 | 'openButtonSelector': '#help-overlay-start' 6 | }); 7 | 8 | tl.pg.init({ 9 | 'custom_open_button': this.defaults.openButtonSelector 10 | }); 11 | 12 | }; 13 | 14 | }(Geosite)); -------------------------------------------------------------------------------- /src/js/PausableEvented.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare', 3 | 'dojo/Evented' 4 | ], 5 | function(declare, Evented) { 6 | "use strict"; 7 | 8 | // Base class which provides a way to pause and resume calls to 9 | // `emit` for a performance boost during batch operations. 10 | return declare([Evented], { 11 | constructor: function() { 12 | this.paused = false; 13 | }, 14 | 15 | // @Override 16 | emit: function() { 17 | if (this.paused) { 18 | return false; 19 | } 20 | return Evented.prototype.emit.apply(this, arguments); 21 | }, 22 | 23 | pauseEvents: function() { 24 | this.paused = true; 25 | }, 26 | 27 | resumeEvents: function() { 28 | this.paused = false; 29 | } 30 | }); 31 | } 32 | ); -------------------------------------------------------------------------------- /src/js/SinglePluginModeHelp.js: -------------------------------------------------------------------------------- 1 | (function (N) { 2 | 'use strict'; 3 | 4 | var $container; 5 | var $pluginToggle; 6 | var $mobileToggle; 7 | var singlePlugin; 8 | var viewModel; 9 | 10 | function initialize(view, $el) { 11 | $container = $el; 12 | $pluginToggle = $('#toggle-plugin-container'); 13 | $mobileToggle = $('#single-plugin-toggle-footer'); 14 | 15 | // Get the content from the developer-provided HTML partial 16 | var content = $('#single-plugin-mode-help-content').html(); 17 | 18 | // Get the template for the help pane 19 | var tmpl = _.template($('#single-plugin-mode-help-template').html()); 20 | 21 | // Insert the template, with the custom contents, to the help pane. 22 | $container.html(tmpl({ content: content })); 23 | 24 | // It's a bit odd to have this here, but there isn't a more discoverable 25 | // place for it to be. 26 | $('#show-single-plugin-mode-help').click(function() { 27 | $container.show(); 28 | $pluginToggle.hide(); 29 | $mobileToggle.hide(); 30 | singlePlugin.get('$uiContainer').hide(); 31 | }); 32 | } 33 | 34 | function close(view) { 35 | $container.hide(); 36 | $pluginToggle.show(); 37 | $mobileToggle.show(); 38 | if (singlePlugin.selected) { 39 | if (!window.matchMedia("screen and (max-width: 736px)").matches || 40 | viewModel.get('pluginContentVisible')) { 41 | singlePlugin.get('$uiContainer').show(); 42 | } 43 | } 44 | } 45 | 46 | N.views = N.views || {}; 47 | N.views.SinglePluginModeHelp = Backbone.View.extend({ 48 | initialize: function (options) { 49 | singlePlugin = options.viewModel.get('plugins').at(0), 50 | viewModel = options.viewModel; 51 | return initialize(this, $('#single-plugin-mode-help-container'), singlePlugin); 52 | }, 53 | events: { 54 | 'click .plugin-off': function (e) { close(this, e); } 55 | } 56 | }); 57 | }(Geosite)); 58 | -------------------------------------------------------------------------------- /src/js/TemplateLoader.js: -------------------------------------------------------------------------------- 1 | /*global Backbone, _, Geosite, $*/ 2 | 3 | (function (N) { 4 | 'use strict'; 5 | /* 6 | 7 | Pre-compile all of the templates stored in 8 | tags. Store 9 | the compiled template functions in the data structure passed 10 | in as an option. 11 | 12 | */ 13 | N.TemplateLoader = function TemplateLoader() { 14 | this.load = function TemplateLoaderLoad(store) { 15 | $("script[type='text/template']").each(function () { 16 | var id = $(this).attr('id'), 17 | html = $(this).html(); 18 | if (store[id]) { 19 | throw ("Duplicate template name: " + id); 20 | } else { 21 | store[id] = _.template(html); 22 | } 23 | }); 24 | }; 25 | }; 26 | 27 | }(Geosite)); -------------------------------------------------------------------------------- /src/js/TimeoutWrapper.js: -------------------------------------------------------------------------------- 1 | /*jslint nomen:true, devel:true */ 2 | /*global _, Geosite, setTimeout, clearTimeout */ 3 | 4 | // a utility for seamlessly promoting normal functions 5 | // to functions that can only be run within a certain 6 | // period of time. 7 | 8 | // requires: 9 | // * success - a function and a number of milliseconds. 10 | // * ms - number of milliseconds to allow function to run. 11 | 12 | // optional: 13 | // * failure - a callback to run when the timeout occurs 14 | // * executeOnce - a callback that should only run once 15 | // in the case of success or failure. This is to avoid 16 | // duplication in your success/error functions. 17 | 18 | (function (N) { 19 | 20 | N.timeoutWrapper = function (args) { 21 | 22 | var noOp = function () { return null; }, 23 | 24 | // required args 25 | success = args.success, 26 | ms = args.ms, 27 | 28 | // optional args 29 | failure = args.failure || noOp, 30 | executeOnce = args.executeOnce || noOp, 31 | 32 | // internal args 33 | _timeoutHappened = false, 34 | _successHappened = false, 35 | _failureWrapper = function (args) { 36 | if (_successHappened === false) { 37 | _timeoutHappened = true; 38 | failure(args); 39 | executeOnce(); 40 | } 41 | }, 42 | _timeoutTracker = setTimeout(_failureWrapper, ms); 43 | 44 | return function (args) { 45 | if (_timeoutHappened === false) { 46 | _successHappened = true; 47 | success(args); 48 | // TODO: not sure if this is necessary 49 | // since the failure function won't 50 | // do anything if successHappened = true 51 | clearTimeout(_timeoutTracker); 52 | executeOnce(); 53 | } 54 | }; 55 | }; 56 | 57 | }(Geosite)); 58 | -------------------------------------------------------------------------------- /src/js/lib/backbone.picky.min.js: -------------------------------------------------------------------------------- 1 | // Backbone.Picky, v0.1.0 2 | // Copyright (c)2012 Derick Bailey, Muted Solutions, LLC. 3 | // Distributed under MIT license 4 | // http://github.com/derickbailey/backbone.picky 5 | Backbone.Picky=function(a,b){var c={};c.SingleSelect=function(a){this.collection=a},b.extend(c.SingleSelect.prototype,{select:function(a){if(a&&this.selected===a)return;this.deselect(),this.selected=a,this.selected.select(),this.trigger("selected",a)},deselect:function(a){if(!this.selected)return;a=a||this.selected;if(this.selected!==a)return;this.selected.deselect(),this.trigger("deselected",this.selected),delete this.selected}}),c.MultiSelect=function(a){this.collection=a,this.selected={}},b.extend(c.MultiSelect.prototype,{select:function(a){if(this.selected[a.cid])return;this.selected[a.cid]=a,a.select(),d(this)},deselect:function(a){if(!this.selected[a.cid])return;delete this.selected[a.cid],a.deselect(),d(this)},selectAll:function(){this.each(function(a){a.select()}),d(this)},selectNone:function(){if(this.selectedLength===0)return;this.each(function(a){a.deselect()}),d(this)},toggleSelectAll:function(){this.selectedLength===this.length?this.selectNone():this.selectAll()}}),c.Selectable=function(a){this.model=a},b.extend(c.Selectable.prototype,{select:function(){if(this.selected)return;this.selected=!0,this.trigger("selected"),this.collection&&this.collection.select(this)},deselect:function(){if(!this.selected)return;this.selected=!1,this.trigger("deselected"),this.collection&&this.collection.deselect(this)},toggleSelected:function(){this.selected?this.deselect():this.select()}});var d=function(a){a.selectedLength=b.size(a.selected);var c=a.selectedLength,d=a.length;if(c===d){a.trigger("select:all",a);return}if(c===0){a.trigger("select:none",a);return}if(c>0&&c=0){var l=a.split(";");e.each(l,function(t,e){""!==e&&n(o,e,r)})}else n(o,a,r);if(f.useOptionsAttr===!0){var s={};s=i({clone:s},r),delete s.lng,t.data(f.optionsAttr,s)}}}function o(t){return this.each(function(){r(e(this),t);var n=e(this).find("["+f.selectorAttr+"]");n.each(function(){r(e(this),t)})})}var f=arguments.length<=2||void 0===arguments[2]?{}:arguments[2];f=i({},a,f),e[f.tName]=t.t.bind(t),e[f.i18nName]=t,e.fn[f.handleName]=o}Object.defineProperty(n,"__esModule",{value:!0});var i=Object.assign||function(t){for(var e=1;e0&&"none"!==b}return!1}();if(w)f(),o.on("click",function(){b()}),n.on("click",function(){b()});else{h.addClass("no-csstransforms3d"),g.hasClass(k)?g.css({left:"-"+s}):g.css({right:"-"+s}),i.css({"overflow-x":"hidden"});var x=!1;f(),o.on("click",function(){x?(e(),x=!1):(d(),x=!0)}),n.on("click",function(){x?(e(),x=!1):(d(),x=!0)})}}(jQuery); -------------------------------------------------------------------------------- /src/js/polyfill.js: -------------------------------------------------------------------------------- 1 | /* 2 | Object.keys polyfill taken from: 3 | https://gist.github.com/atk/1034464 4 | */ 5 | Object.keys = Object.keys || 6 | function( 7 | o, // object 8 | k, // key 9 | r // result array 10 | ) { 11 | // initialize object and result 12 | r = []; 13 | // iterate over object keys 14 | for (k in o) 15 | // fill result array with non-prototypical keys 16 | r.hasOwnProperty.call(o, k) && r.push(k); 17 | // return result 18 | return r; 19 | }; 20 | 21 | /* 22 | Array.isArray polyfill from: 23 | https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray 24 | */ 25 | if (!Array.isArray) { 26 | Array.isArray = function (vArg) { 27 | return Object.prototype.toString.call(vArg) === "[object Array]"; 28 | }; 29 | } -------------------------------------------------------------------------------- /src/js/unittest.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "dojo/Deferred", 3 | "dojo/promise/all", 4 | "underscore" 5 | ], 6 | function(Deferred, 7 | all, 8 | _) { 9 | "use strict"; 10 | 11 | function runAllTests(tests) { 12 | var defers = _.map(tests, function(test) { 13 | var defer = new Deferred(), 14 | done = function() { 15 | defer.resolve(); 16 | }; 17 | 18 | // Fail the test if it takes longer than 1000 ms to execute. 19 | setTimeout(function() { 20 | if (!defer.isFulfilled()) { 21 | console.debug(test.name + ' did not complete after the timeout period'); 22 | defer.reject(); 23 | } 24 | }, 1000); 25 | 26 | // Pass a "done" callback to any test that accepts 1 argument. 27 | if (test.length === 1) { 28 | test(done); 29 | } else { 30 | test(); 31 | done(); 32 | } 33 | 34 | return defer; 35 | }); 36 | var promise = all(defers); 37 | return promise.then(function() { 38 | console.debug(defers.length + ' tests passed'); 39 | }, function() { 40 | console.debug('Some tests failed'); 41 | }); 42 | } 43 | 44 | function assertTrue(value) { 45 | if (!value) { 46 | throw new Error('Assertion failed'); 47 | } 48 | } 49 | 50 | return { 51 | assertTrue: assertTrue, 52 | runAllTests: runAllTests 53 | }; 54 | } 55 | ); 56 | -------------------------------------------------------------------------------- /src/js/util/ajax.js: -------------------------------------------------------------------------------- 1 | //= require underscore 2 | define(['esri/request'], 3 | function(request) { 4 | 'use strict'; 5 | 6 | var cache = {}, 7 | promises = {}; 8 | 9 | function get(url) { 10 | return cache[url]; 11 | } 12 | 13 | // Fetch data from `url` and store the result in `cache` (memoized). 14 | var fetch = function(url, options) { 15 | var options = options || {}, 16 | settings = _.defaults(options, { 17 | format: 'json', 18 | content: {f: 'json'} 19 | }); 20 | 21 | if (typeof promises[url] === 'undefined') { 22 | promises[url] = request({ 23 | url: url, 24 | content: settings.content, 25 | handleAs: settings.format, 26 | callbackParamName: 'callback', 27 | timeout: 20000 28 | }).then(function(data) { 29 | cache[url] = data; 30 | }, function(error) { 31 | cache[url] = error; 32 | }).then(function() { 33 | return cache[url]; 34 | }); 35 | } 36 | return promises[url]; 37 | }; 38 | 39 | function isFetching(url) { 40 | return typeof promises[url] !== 'undefined'; 41 | } 42 | 43 | function isCached(url) { 44 | return typeof cache[url] !== 'undefined'; 45 | } 46 | 47 | function shouldFetch(url) { 48 | return !isFetching(url) && !isCached(url); 49 | } 50 | 51 | return { 52 | get: get, 53 | fetch: fetch, 54 | isCached: isCached, 55 | shouldFetch: shouldFetch 56 | }; 57 | } 58 | ); -------------------------------------------------------------------------------- /src/js/widgets/map_utils/export/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare' 3 | ], 4 | function(declare) { 5 | 'use strict'; 6 | 7 | return declare(null, { 8 | constructor: function(dispatcher) { 9 | this.dispatcher = dispatcher; 10 | }, 11 | 12 | execute: function() { 13 | this.dispatcher.trigger('export-map:pane-0'); 14 | } 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/js/widgets/map_utils/full_extent/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare', 3 | 'esri/geometry/Extent', 4 | 'esri/SpatialReference' 5 | ], 6 | function (declare, 7 | Extent, 8 | SpatialReference) { 9 | 'use strict'; 10 | 11 | var LatLng = new SpatialReference({ wkid: 4326 }); 12 | 13 | return declare(null, { 14 | constructor: function(map, extent) { 15 | this.map = map; 16 | this.initialExtent = new Extent( 17 | extent[0], 18 | extent[1], 19 | extent[2], 20 | extent[3], 21 | LatLng); 22 | }, 23 | 24 | execute: function() { 25 | this.map.setExtent(this.initialExtent); 26 | } 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/js/widgets/map_utils/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'use!Geosite', 3 | 'dojo/_base/declare', 4 | 'js/widgets/map_utils/measure/main.js', 5 | 'js/widgets/map_utils/full_extent/main.js', 6 | 'js/widgets/map_utils/export/main.js', 7 | 'js/widgets/map_utils/share/main.js' 8 | ], 9 | function(N, 10 | declare, 11 | MeasureCommand, 12 | FullExtentCommand, 13 | ExportCommand, 14 | ShareCommand) { 15 | 'use strict'; 16 | 17 | return Backbone.View.extend({ 18 | events: { 19 | 'click [data-command]': 'onCommand' 20 | }, 21 | 22 | initialize: function(options) { 23 | this.map = options.map; 24 | this.app = options.app; 25 | this.regionData = options.regionData; 26 | }, 27 | 28 | initializeCommand: function(command) { 29 | var map = this.map; 30 | var dispatcher = this.app.dispatcher; 31 | var initialExtent = this.regionData.initialExtent; 32 | 33 | switch (command) { 34 | case 'measure': 35 | return new MeasureCommand(map); 36 | case 'zoom': 37 | return new FullExtentCommand(map, initialExtent); 38 | case 'export': 39 | return new ExportCommand(dispatcher); 40 | case 'share': 41 | return new ShareCommand(dispatcher); 42 | } 43 | 44 | throw new Error('Command not supported'); 45 | }, 46 | 47 | cancelCommand: function() { 48 | if (this.command && this.command.cancel) { 49 | this.command.cancel(); 50 | } 51 | this.command = null; 52 | }, 53 | 54 | onCommand: function(e) { 55 | var $el = $(e.currentTarget), 56 | command = $el.data('command'); 57 | 58 | this.cancelCommand(); 59 | this.command = this.initializeCommand(command); 60 | this.command.execute(); 61 | } 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /src/js/widgets/map_utils/measure/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare', 3 | 'js/widgets/map_utils/measure/AgsMeasure.js' 4 | ], 5 | function(declare, 6 | AgsMeasure) { 7 | 'use strict'; 8 | 9 | var introTemplate = $('#template-measure-intro').html(); 10 | var tooltipTemplate = $('#template-measure-tooltip').html(); 11 | var infoBubbleTemplate = $('#template-measure-infobubble').html(); 12 | 13 | return declare(null, { 14 | constructor: function(map) { 15 | this.agsMeasure = new AgsMeasure({ 16 | map: map, 17 | introTemplate: introTemplate, 18 | tooltipTemplate: tooltipTemplate, 19 | infoBubbleTemplate: infoBubbleTemplate 20 | }); 21 | this.agsMeasure.initialize(); 22 | }, 23 | 24 | execute: function() { 25 | this.agsMeasure.activate(); 26 | }, 27 | 28 | cancel: function() { 29 | this.agsMeasure.deactivate(); 30 | } 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /src/js/widgets/map_utils/share/main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'dojo/_base/declare' 3 | ], 4 | function(declare) { 5 | 'use strict'; 6 | 7 | return declare(null, { 8 | constructor: function(dispatcher) { 9 | this.dispatcher = dispatcher; 10 | }, 11 | 12 | execute: function() { 13 | this.dispatcher.trigger('save-share'); 14 | } 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/plugins/launchpad/icon_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/plugins/launchpad/icon_sm.png -------------------------------------------------------------------------------- /src/plugins/launchpad/infographic-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/plugins/launchpad/infographic-icon.png -------------------------------------------------------------------------------- /src/plugins/launchpad/infographic.html: -------------------------------------------------------------------------------- 1 |
2 |

This is a test

3 | 4 |
-------------------------------------------------------------------------------- /src/plugins/launchpad/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Start exploring": "Start exploring", 3 | "One-click maps": "One-click maps", 4 | "Partners": "Partners", 5 | "Go": "Go" 6 | } -------------------------------------------------------------------------------- /src/plugins/launchpad/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Start exploring": "Comienza a explorar", 3 | "One-click maps": "Mapas con un solo clic", 4 | "Partners": "Socios", 5 | "Go": "Entrar" 6 | } -------------------------------------------------------------------------------- /src/plugins/launchpad/overrides.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /src/plugins/launchpad/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ 3 | "plugins/launchpad/style.css" 4 | ], 5 | "use": {} 6 | } 7 | -------------------------------------------------------------------------------- /src/plugins/launchpad/style.css: -------------------------------------------------------------------------------- 1 | .launchpad-plugin { 2 | padding: 10px; 3 | height: calc(90vh - 60px); 4 | } 5 | .launchpad-plugin .plugins div, 6 | .launchpad-plugin .scenarios div { 7 | display: inline-block; 8 | width: 83%; 9 | } 10 | .launchpad-plugin .plugins .button, 11 | .launchpad-plugin .scenarios .button { 12 | float: right; 13 | } 14 | .launchpad-plugin .partners li { 15 | display: inline-block; 16 | } 17 | .launchpad-plugin .partners img { 18 | height: 60px; 19 | margin: 5px 10px; 20 | } 21 | .launchpad-plugin ul { 22 | margin: 0; 23 | list-style-type: none; 24 | padding: 0; 25 | } 26 | .launchpad-plugin .plugins .button.truncate-toggle, .scenarios .button.truncate-toggle { 27 | padding: 2px; 28 | font-size: 0.7em; 29 | width: 35%; 30 | float: none; 31 | } 32 | .infographic-icon { 33 | padding: 2px !important; 34 | height: 28px; 35 | position: absolute; 36 | top: 6px; 37 | margin-left: 4px; 38 | z-index: 2600; 39 | } 40 | -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/plugins/subregion_toggle/icon.png -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Subregion Toggle": "Subregion Toggle", 3 | "Show and hide subregion areas on the map": "Show and hide subregion areas on the map" 4 | } -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Subregion Toggle": "Subregión de Palanca", 3 | "Show and hide subregion areas on the map": "Mostrar y ocultar áreas subregión en el mapa" 4 | } -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/main.js: -------------------------------------------------------------------------------- 1 | define( 2 | ["dojo/_base/declare", "framework/PluginBase"], 3 | function (declare, PluginBase) { 4 | return declare(PluginBase, { 5 | toolbarName: "Subregion Toggle", 6 | fullName: "Show and hide subregion areas on the map", 7 | toolbarType: "map", 8 | allowIdentifyWhenActive: true, 9 | closeOthersWhenActive: false, 10 | 11 | initialize: function (args) { 12 | declare.safeMixin(this, args); 13 | 14 | if (this.app.regionConfig.subregions.hideByDefault) { 15 | this.activate(); 16 | } 17 | }, 18 | 19 | renderLauncher: function () { 20 | return '
'; 21 | }, 22 | 23 | activate: function () { 24 | var mapId = this.map.getMapId(); 25 | this.app.dispatcher.trigger('subregion-toggle:toggle', mapId); 26 | }, 27 | 28 | validate: function(regionData) { 29 | // This plugin is only valid if there are subregions present in the config 30 | return !!regionData.subregions || !_.isEmpty(regionData.subregions); 31 | }, 32 | 33 | getClassName: function() { 34 | return 'subregion-toggle'; 35 | }, 36 | 37 | subregionActivated: function(subregion, pane) { 38 | $('#map-' + pane.get('paneNumber')).find('.' + this.getClassName()).hide(); 39 | }, 40 | 41 | subregionDeactivated: function(subregion, pane) { 42 | $('#map-' + pane.get('paneNumber')).find('.' + this.getClassName()).show(); 43 | } 44 | 45 | }); 46 | } 47 | ); -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ 3 | "plugins/subregion_toggle/subregion-toggle.css" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/plugins/subregion_toggle/subregion-toggle.css: -------------------------------------------------------------------------------- 1 | .content .map .subregion-toggle { 2 | background-image: url(icon.png); 3 | } -------------------------------------------------------------------------------- /src/requirements.txt: -------------------------------------------------------------------------------- 1 | Jinja2==2.10 2 | jsonschema==2.6.0 3 | -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/FutureHabitat_c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/sample_plugins/identify_point/FutureHabitat_c.jpg -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/html/infographic.html: -------------------------------------------------------------------------------- 1 |
2 |

This is a test

3 | 4 |
-------------------------------------------------------------------------------- /src/sample_plugins/identify_point/html/print-form.html: -------------------------------------------------------------------------------- 1 |
2 | 6 |
7 | 11 |
12 | 16 | 20 |
-------------------------------------------------------------------------------- /src/sample_plugins/identify_point/icon_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/sample_plugins/identify_point/icon_sm.png -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Identify Point": "Identify Point", 3 | "Identify point sample plugin": "Identify point sample plugin", 4 | "Click any point on the map to display Latitude and Longitude": "Click any point on the map to display Latitude and Longitude", 5 | "You clicked on latitude %f longitude %f": "You clicked on latitude %f longitude %f" 6 | } 7 | -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/main.css: -------------------------------------------------------------------------------- 1 | hr { 2 | margin: 20px 0; 3 | } 4 | 5 | .accord { 6 | height: 200px; 7 | margin-bottom: 100px; 8 | } 9 | 10 | .sample { 11 | float: right; 12 | } -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/north-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/sample_plugins/identify_point/north-arrow.png -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ 3 | "sample_plugins/identify_point/main.css" 4 | ], 5 | "use": { } 6 | } -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/print.css: -------------------------------------------------------------------------------- 1 | @media print { 2 | @page { 3 | size: portrait; 4 | } 5 | 6 | #legend-container-0 { 7 | position: absolute; 8 | bottom: 25px; 9 | right: 10px; 10 | } 11 | 12 | #map-0 { 13 | margin-top: 1in; 14 | height: 8in; 15 | width: 8in; 16 | } 17 | } 18 | 19 | #north-arrow-img { 20 | height: 60px; 21 | width: 70px; 22 | position: absolute; 23 | bottom: 20px; 24 | right: 20px; 25 | z-index: 1000; 26 | } 27 | 28 | #logo-img { 29 | height: 60px; 30 | width: 200px; 31 | } 32 | 33 | /** 34 | Rules related to the print preview map: 35 | 1. Overrides to the print modal to fit the map 36 | 2. Overrides to the map to better fit in the modal 37 | **/ 38 | 39 | .print-preview { 40 | width: 100%; 41 | margin-top: 10px; 42 | } 43 | 44 | .print-preview-map-container { 45 | width: 100%; 46 | height: 100%; 47 | } 48 | 49 | .print-preview-map-container #map-0.map { 50 | position: relative; 51 | height: 300px; 52 | width: 300px; 53 | margin: 10px auto; 54 | } 55 | 56 | .print-preview-map-container #legend-container-0 { 57 | display: none !important; 58 | } 59 | 60 | .popover-section { 61 | height: 400px; 62 | } 63 | 64 | .print-modal-confirm-container { 65 | position: initial; 66 | } 67 | 68 | .map-tools { 69 | display: none; 70 | } 71 | 72 | .basemap-selector { 73 | display: none; 74 | } 75 | 76 | #map-0_zoom_slider { 77 | top: 10px; 78 | right: 10px; 79 | } 80 | 81 | .print-modal-confirm-container { 82 | position: relative !important; 83 | margin-top: 30px; 84 | bottom: 0px !important; 85 | left: 0px !important; 86 | } -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/sample_plugins/identify_point/splash.png -------------------------------------------------------------------------------- /src/sample_plugins/identify_point/tnc-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/src/sample_plugins/identify_point/tnc-logo.png -------------------------------------------------------------------------------- /styleguide/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // measures the time each task takes 4 | require('time-grunt')(grunt); 5 | 6 | // load grunt config 7 | require('load-grunt-config')(grunt); 8 | 9 | }; -------------------------------------------------------------------------------- /styleguide/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Azavea 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 | -------------------------------------------------------------------------------- /styleguide/Readme.md: -------------------------------------------------------------------------------- 1 | # Mantle 2 | version: 0.1.0 3 | A front end framework for use with GIS applications developed and maintained by Azavea. 4 | 5 | --- 6 | 7 | ## Getting Started 8 | To get up and running, run `npm install` in your CLI in the project directory. Then run `grunt`. Your browser should automatically open `localhost:3000`. That's it. You are good to go. 9 | 10 | ## Upgrade the styleguide for GeositeFramework 11 | * Get Started, from above 12 | * Copy `app/assets/css/main.css` to `src/GeositeFramework/css/styleguide.css` 13 | * Move the contents of `app/` to the branch `gh-pages` and push to origin 14 | --- 15 | 16 | ## Grunt 17 | ### Grunt Plugins 18 | * [Grunt Browser Sync](https://www.npmjs.com/package/grunt-browser-sync) 19 | * [Grunt Contrib Watch](https://www.npmjs.com/package/grunt-contrib-watch) 20 | * [Grunt Postcss](https://www.npmjs.com/package/grunt-postcss) 21 | * Autoprefixer 22 | * cssnano 23 | * [Grunt Sass](https://www.npmjs.com/package/grunt-sass) 24 | * [Load Grunt Config](https://www.npmjs.com/package/load-grunt-config) 25 | * [Load Grunt Tasks](https://www.npmjs.com/package/load-grunt-tasks) 26 | * [Time Grunt](https://www.npmjs.com/package/time-grunt) 27 | * [Grunt Newer](https://www.npmjs.com/package/grunt-newer) 28 | * Not currently in use 29 | * Grunt Concurrent 30 | * Under consideration 31 | 32 | --- 33 | 34 | #### Grunt Browser Sync 35 | Live reload and browser syncing. This will automatically open `localhost:3000` and you can access broswesync settings at `localhost:3001` 36 | 37 | #### Grunt Contrib Watch 38 | Run predefined tasks whenever watched file patterns are added, changed or deleted. Currently this will compile sass and run postcss tasks 39 | 40 | #### Grunt Postcss 41 | Applies several post-processors to your CSS using PostCSS. Currently will run Autoprfixer and cssnano immediately after sass compiling 42 | 43 | #### Grunt Sass 44 | Compile Sass to CSS using node-sass/libsass 45 | 46 | #### Load Grunt Config 47 | Allows us to break up the Gruntfile config by task. Makes for a cleaner Gruntfile 48 | 49 | #### Load Grunt Tasks 50 | Load multiple grunt tasks using globbing patterns. 51 | 52 | #### Time Grunt 53 | Display the elapsed execution time of grunt tasks 54 | 55 | #### Grunt Newer 56 | *Not Currently In Use* Run Grunt tasks with only those source files modified since the last successful run. 57 | 58 | #### Grunt Concurrent 59 | *Under Consideration* Run grunt tasks concurrently 60 | 61 | #### grunt-html-build 62 | *Consider* 63 | -------------------------------------------------------------------------------- /styleguide/app/assets/fonts/fontello/css/animation.css: -------------------------------------------------------------------------------- 1 | /* 2 | Animation example, for spinners 3 | */ 4 | .animate-spin { 5 | -moz-animation: spin 2s infinite linear; 6 | -o-animation: spin 2s infinite linear; 7 | -webkit-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | display: inline-block; 10 | } 11 | @-moz-keyframes spin { 12 | 0% { 13 | -moz-transform: rotate(0deg); 14 | -o-transform: rotate(0deg); 15 | -webkit-transform: rotate(0deg); 16 | transform: rotate(0deg); 17 | } 18 | 19 | 100% { 20 | -moz-transform: rotate(359deg); 21 | -o-transform: rotate(359deg); 22 | -webkit-transform: rotate(359deg); 23 | transform: rotate(359deg); 24 | } 25 | } 26 | @-webkit-keyframes spin { 27 | 0% { 28 | -moz-transform: rotate(0deg); 29 | -o-transform: rotate(0deg); 30 | -webkit-transform: rotate(0deg); 31 | transform: rotate(0deg); 32 | } 33 | 34 | 100% { 35 | -moz-transform: rotate(359deg); 36 | -o-transform: rotate(359deg); 37 | -webkit-transform: rotate(359deg); 38 | transform: rotate(359deg); 39 | } 40 | } 41 | @-o-keyframes spin { 42 | 0% { 43 | -moz-transform: rotate(0deg); 44 | -o-transform: rotate(0deg); 45 | -webkit-transform: rotate(0deg); 46 | transform: rotate(0deg); 47 | } 48 | 49 | 100% { 50 | -moz-transform: rotate(359deg); 51 | -o-transform: rotate(359deg); 52 | -webkit-transform: rotate(359deg); 53 | transform: rotate(359deg); 54 | } 55 | } 56 | @-ms-keyframes spin { 57 | 0% { 58 | -moz-transform: rotate(0deg); 59 | -o-transform: rotate(0deg); 60 | -webkit-transform: rotate(0deg); 61 | transform: rotate(0deg); 62 | } 63 | 64 | 100% { 65 | -moz-transform: rotate(359deg); 66 | -o-transform: rotate(359deg); 67 | -webkit-transform: rotate(359deg); 68 | transform: rotate(359deg); 69 | } 70 | } 71 | @keyframes spin { 72 | 0% { 73 | -moz-transform: rotate(0deg); 74 | -o-transform: rotate(0deg); 75 | -webkit-transform: rotate(0deg); 76 | transform: rotate(0deg); 77 | } 78 | 79 | 100% { 80 | -moz-transform: rotate(359deg); 81 | -o-transform: rotate(359deg); 82 | -webkit-transform: rotate(359deg); 83 | transform: rotate(359deg); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /styleguide/app/assets/fonts/fontello/font/mantle.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/fonts/fontello/font/mantle.eot -------------------------------------------------------------------------------- /styleguide/app/assets/fonts/fontello/font/mantle.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/fonts/fontello/font/mantle.ttf -------------------------------------------------------------------------------- /styleguide/app/assets/fonts/fontello/font/mantle.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/fonts/fontello/font/mantle.woff -------------------------------------------------------------------------------- /styleguide/app/assets/fonts/fontello/font/mantle.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/fonts/fontello/font/mantle.woff2 -------------------------------------------------------------------------------- /styleguide/app/assets/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/images/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/js/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/js/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/js/main.js: -------------------------------------------------------------------------------- 1 | var map = L.map('map', { 2 | center: [40.000, -75.1639], 3 | zoom: 12 4 | }); 5 | var Stamen_TonerLite = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', { 6 | attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap', 7 | subdomains: 'abcd', 8 | minZoom: 0, 9 | maxZoom: 20, 10 | ext: 'png' 11 | }).addTo(map); 12 | 13 | 14 | // Map Attribution 15 | // Register click event 16 | $('.map-attribution').click(function(e){ 17 | $(this).toggleClass('active'); 18 | }) -------------------------------------------------------------------------------- /styleguide/app/assets/js/mobileTable.jquery.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | jQuery.fn.extend({ 4 | 5 | mobileTable: function () { 6 | 7 | var $table = $(this), 8 | $headers = $table.find("thead th"), 9 | $rows = $table.find("tbody tr"), 10 | attribute = "data-th"; 11 | 12 | // Generate array that contains text from each header 13 | 14 | var headerValues = $headers.map(function(key, header){ 15 | return $(header).text(); 16 | }); 17 | 18 | // Loop through each column in each row, adding the associated headerText 19 | // to the `data-th` attribute 20 | 21 | $.each($rows, function(key, row) { 22 | var $columns = $(row).find("td, th"); 23 | $.each($columns, function(key, column) { 24 | var $column = $(column), 25 | headerValue = headerValues[key]; 26 | $column.attr(attribute, headerValue); 27 | }); 28 | }); 29 | 30 | // Add mobile class which will recieve styling for mobile 31 | 32 | $table.addClass("table-mobile-stacked"); 33 | 34 | } 35 | 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/_demo.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/_demo.scss -------------------------------------------------------------------------------- /styleguide/app/assets/sass/base/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/base/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/sass/base/_base.scss: -------------------------------------------------------------------------------- 1 | /* Border-Box */ 2 | *, 3 | *:before, 4 | *:after { 5 | box-sizing: inherit; 6 | } 7 | 8 | html { 9 | font-size: 62.5%; 10 | box-sizing: border-box; 11 | } 12 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/components/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_alert.scss: -------------------------------------------------------------------------------- 1 | // Alert 2 | 3 | .alert { 4 | padding: $alert-padding-vertical $alert-padding-horizontal; 5 | border-radius: $alert-border-radius; 6 | border: 2px solid transparent; 7 | font-size: $alert-font-size; 8 | } 9 | 10 | @include generate-alert(); 11 | 12 | @include generate-alert(-primary, $brand-primary); 13 | 14 | @include generate-alert(-secondary, $brand-secondary); 15 | 16 | @include generate-alert(-danger, $brand-danger); 17 | 18 | @include generate-alert(-warning, $brand-warning); 19 | 20 | .alert-heading { 21 | font-size: $alert-heading-font-size; 22 | font-weight: $alert-heading-font-weight; 23 | } 24 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | .row { 3 | display: flex; 4 | flex-wrap: wrap; 5 | margin-bottom: 1rem; 6 | 7 | &.nowrap { 8 | flex-wrap: nowrap; 9 | overflow: auto; 10 | } 11 | } 12 | 13 | // Alignment on a row 14 | .align-right { 15 | justify-content: flex-end; 16 | } 17 | 18 | .align-center { 19 | justify-content: center; 20 | } 21 | 22 | .align-justify { 23 | justify-content: space-between; 24 | } 25 | 26 | .align-spaced { 27 | justify-content: space-around; 28 | } 29 | 30 | // Row's column vertical aligment 31 | .columns-top { 32 | align-items: flex-start; 33 | } 34 | 35 | .columns-center { 36 | align-items: center; 37 | } 38 | 39 | .columns-bottom { 40 | align-items: flex-end; 41 | } 42 | 43 | .columns-stretch { 44 | align-items: stretch; 45 | } 46 | 47 | // Columns 48 | // $column-count in variables 49 | .column { 50 | flex: 1; 51 | padding: $column-padding; 52 | } 53 | 54 | @for $i from 1 through $column-count { 55 | .column-#{$i} { 56 | flex: none; 57 | padding: $column-padding; 58 | width: ($i/$column-count) * 100%; 59 | } 60 | } 61 | 62 | // Individual column vertical aligment 63 | .column-top { 64 | align-self: flex-start; 65 | } 66 | 67 | .column-center { 68 | align-self: center; 69 | } 70 | 71 | .column-bottom { 72 | align-self: flex-end; 73 | } 74 | 75 | .column-stretch { 76 | align-self: stretch; 77 | } 78 | 79 | 80 | // Column Stacking 81 | @include respond-to(md-down) { 82 | .stack-md { 83 | flex-direction: column; 84 | > [class^=column-] { 85 | width: 100%; 86 | } 87 | } 88 | } 89 | 90 | @include respond-to(sm-down) { 91 | .stack-sm { 92 | flex-direction: column; 93 | > [class^=column-] { 94 | width: 100%; 95 | } 96 | } 97 | } 98 | 99 | @include respond-to(xs) { 100 | .stack-xs { 101 | flex-direction: column; 102 | > [class^=column-] { 103 | width: 100%; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_map-attribution.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Map Attribution 3 | * Custom map attribution component to use instead of Leaflet/OpenLayers/etc component. 4 | * * * */ 5 | 6 | .leaflet-control-attribution { 7 | @if $leaflet-control-attribution-on == false { 8 | display: none; 9 | } 10 | } 11 | 12 | .map-attribution { 13 | position: absolute; 14 | z-index: $zindex-map-attribution; 15 | cursor: pointer; 16 | font-size: $map-attribution-font-size; 17 | padding: 0.2em 0.5em; 18 | background-color: rgba(255, 255, 255, 0.75); 19 | user-select: none; 20 | color: $map-attribution-font-color; 21 | 22 | &.active { 23 | .map-attribution-label { 24 | display: none; 25 | } 26 | .map-attribution-text { 27 | display: inline; 28 | } 29 | .map-attribution-button { 30 | background-color: lighten($brand-primary, 20%); 31 | } 32 | } 33 | 34 | &.bottom { 35 | bottom: 0; 36 | } 37 | 38 | &.left { 39 | left: 0; 40 | } 41 | 42 | &.right { 43 | right: 0; 44 | } 45 | 46 | &.top { 47 | top: 0; 48 | } 49 | } 50 | 51 | .map-attribution-text { 52 | // Hide attribution text by default 53 | display: none; 54 | } 55 | 56 | .map-attribution-button { 57 | background-color: transparent; 58 | border: 0; 59 | padding: 0; 60 | cursor: pointer; 61 | border-radius: 100%; 62 | color: #fff; 63 | background-color: $brand-primary; 64 | width: 1.4em; 65 | height: 1.4em; 66 | font-size: 1em; 67 | text-align: center; 68 | line-height: 1.4em; 69 | } 70 | 71 | .map-attribution-text, .map-attribution-label { 72 | margin-right: 0.25rem; 73 | } 74 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_modal.scss: -------------------------------------------------------------------------------- 1 | // Modal, Bootstrap 2 | 3 | .button-modal-close { 4 | color: $gray-4; 5 | float: right; 6 | border: 0; 7 | margin-right: -1.5rem; 8 | font-size: $modal-font-size; 9 | margin-top: -1.0rem; 10 | padding-right: 1.0rem; 11 | padding-left: 1rem; 12 | &:hover, 13 | &:active, 14 | &:focus { 15 | background-color: transparent; 16 | color: $gray-5; 17 | } 18 | } 19 | 20 | .modal-dialog { 21 | position: relative; 22 | max-width: $modal-width; 23 | margin: 2rem auto; 24 | .modal-large & { 25 | max-width: $modal-width-large; 26 | } 27 | .modal-small & { 28 | max-width: $modal-width-small; 29 | } 30 | @include respond-to(xxs) { 31 | margin: 1rem; 32 | } 33 | } 34 | 35 | .modal-open { 36 | overflow: hidden; 37 | } 38 | 39 | .modal-open .modal { 40 | overflow-x: hidden; 41 | overflow-y: auto; 42 | } 43 | 44 | .modal { 45 | display: none; 46 | overflow: hidden; 47 | position: fixed; 48 | top: 0; 49 | right: 0; 50 | bottom: 0; 51 | left: 0; 52 | z-index: 1050; 53 | outline: 0; 54 | } 55 | 56 | .modal-content { 57 | position: relative; 58 | background-color: #ffffff; 59 | border-radius: $modal-border-radius; 60 | background-clip: padding-box; 61 | outline: 0; 62 | } 63 | 64 | .modal-backdrop { 65 | position: fixed; 66 | top: 0; 67 | right: 0; 68 | bottom: 0; 69 | left: 0; 70 | z-index: 1040; 71 | background-color: #000000; 72 | } 73 | 74 | .modal-backdrop.in { 75 | opacity: 0.5; 76 | } 77 | 78 | .modal-title { 79 | margin-top: 0; 80 | } 81 | 82 | .modal-header { 83 | padding: $modal-heading-padding; 84 | border-bottom: 1px solid $gray-1; 85 | @include clearfix; 86 | } 87 | 88 | .modal-body { 89 | position: relative; 90 | padding: $modal-body-padding; 91 | } 92 | 93 | .modal-footer { 94 | padding: $modal-footer-padding; 95 | text-align: right; 96 | border-top: 1px solid $gray-1; 97 | @include clearfix; 98 | } 99 | 100 | .modal-scrollbar-measure { 101 | position: absolute; 102 | top: -9999px; 103 | width: 50px; 104 | height: 50px; 105 | overflow: scroll; 106 | } 107 | 108 | 109 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_navbar.scss: -------------------------------------------------------------------------------- 1 | nav { 2 | flex-shrink: 0; 3 | } 4 | 5 | .nav-primary { 6 | background-color: #666; 7 | height: 40px; 8 | } -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .sidebar-with-nav-vertical { 2 | display: flex; 3 | } 4 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_slider.scss: -------------------------------------------------------------------------------- 1 | .slider-container .ui-slider-tip { 2 | visibility: visible; 3 | opacity: 1; 4 | top: -30px; 5 | } 6 | 7 | .slider-container .ui-slider-pips [class*=ui-slider-pip-selected], 8 | .slider-container .ui-slider-pips [class*=ui-slider-pip-initial] { 9 | color: #999 !important; 10 | font-weight: normal !important; 11 | } 12 | 13 | .slider-container { 14 | margin: 16px 0 40px; 15 | } 16 | 17 | .slider-container .ui-state-default, 18 | .slider-container .ui-widget-content .ui-state-default, 19 | .slider-container .ui-widget-header .ui-state-default { 20 | border-radius: 100% !important; 21 | box-shadow: 0 1px 1px rgba(16,22,26,.1) !important; 22 | background: linear-gradient(180deg,hsla(0,0%,100%,.1),hsla(0,0%,100%,0)) 0 no-repeat,50% no-repeat #0096D6 !important; 23 | border-color: rgba(16,22,26,.1) rgba(16,22,26,.1) rgba(16,22,26,.3) !important; 24 | width: 17px !important; 25 | height: 17px !important; 26 | } 27 | 28 | .slider-container .ui-slider-float .ui-slider-tip:after, 29 | .slider-container .ui-slider-float .ui-slider-pip .ui-slider-tip-label:after { 30 | border-top-color: #ccd5d5 !important; 31 | } 32 | 33 | .slider-container .ui-slider-float .ui-slider-tip, 34 | .slider-container .ui-slider-float .ui-slider-tip-label { 35 | background: #ccd5d5 !important; 36 | border-radius: 3px !important; 37 | border: 1px solid #ccd5d5 !important; 38 | color: #555 !important; 39 | } 40 | 41 | .slider-container .ui-slider-float .ui-slider-tip:before, 42 | .slider-container .ui-slider-float .ui-slider-pip .ui-slider-tip-label:before { 43 | border-top-color: #ccc !important; 44 | } 45 | 46 | .slider-container .ui-slider-pips [class*=ui-slider-pip-selected] .ui-slider-line, 47 | .slider-container .ui-slider-pips .ui-slider-pip-inrange .ui-slider-line { 48 | background: #999 !important; 49 | } 50 | 51 | .slider-container .ui-slider-pips:not(.ui-slider-disabled) .ui-slider-pip:hover .ui-slider-label { 52 | font-weight: normal !important; 53 | } 54 | 55 | .slider-container .slider.ui-widget-content { 56 | background: transparent !important; 57 | } 58 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_table.scss: -------------------------------------------------------------------------------- 1 | .table { 2 | width: 100%; 3 | border-collapse: collapse; 4 | border: 1px solid $border-color; 5 | margin-bottom: 1rem; 6 | 7 | thead { 8 | text-align: left; 9 | 10 | th, td { 11 | font-weight: 600; 12 | } 13 | } 14 | 15 | tbody { 16 | text-align: left; 17 | 18 | > tr:hover { 19 | background-color: #f3f3f3; 20 | } 21 | } 22 | 23 | th, 24 | td { 25 | border-bottom: 1px solid $border-color; 26 | padding: 2rem 1.5rem; 27 | } 28 | } 29 | 30 | .table-responsive { 31 | overflow: auto; 32 | white-space: nowrap; 33 | } 34 | 35 | .table-mobile-stacked { 36 | @include respond-to(xs) { 37 | 38 | thead { 39 | display: none; 40 | } 41 | 42 | tr { 43 | border-bottom: 1px solid $border-color; 44 | } 45 | 46 | tbody [data-th] { 47 | display: block; 48 | text-align: right; 49 | border: none; 50 | padding: 1rem; 51 | 52 | &:before { 53 | content: attr(data-th); 54 | font-weight: 600; 55 | display: inline-block; 56 | margin-right: 1rem; 57 | float: left; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_tabs.scss: -------------------------------------------------------------------------------- 1 | .nav-tabs>li.active>a, .nav-tabs>li.active>a:focus, .nav-tabs>li.active>a:hover { 2 | color: #111; 3 | cursor: default; 4 | background-color: #fff; 5 | -webkit-box-shadow: 0px 2px 0px 0px $brand-primary;; 6 | -moz-box-shadow: 0px 2px 0px 0px $brand-primary;; 7 | box-shadow: 0px 2px 0px 0px $brand-primary;; 8 | } 9 | 10 | .nav-tabs>li>a { 11 | margin-right: 2px; 12 | border: 1px solid transparent; 13 | border-radius: 3px 3px 0 0; 14 | color: #7F8FA4; 15 | } 16 | 17 | .nav>li>a { 18 | position: relative; 19 | display: block; 20 | padding: 10px 0px; 21 | margin-top: 3px; 22 | margin: 3px 15px 0px 15px; 23 | } 24 | 25 | .nav-tabs>li { 26 | float: left; 27 | margin-bottom: -1px; 28 | } 29 | 30 | .nav>li { 31 | position: relative; 32 | display: block; 33 | } 34 | 35 | .nav-tabs { 36 | padding-left: 0; 37 | margin-bottom: 0; 38 | background-color: #ffffff; 39 | @include clearfix; 40 | } 41 | 42 | .tab-content>.tab-pane { 43 | display: none; 44 | } 45 | 46 | .tab-content>.active { 47 | display: block; 48 | } 49 | 50 | .sidebar-content { 51 | .tab-content { 52 | padding: 10px; 53 | background: #ffffff; 54 | } 55 | } 56 | 57 | .sidebar-content-heading { 58 | margin-top: 1rem; 59 | } 60 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/components/_tooltip.scss: -------------------------------------------------------------------------------- 1 | // Tooltip, Bootstrap 2 | 3 | .tooltip { 4 | position: absolute; 5 | z-index: 1070; 6 | display: block; 7 | font-family: $tooltip-font-family; 8 | letter-spacing: normal; 9 | line-break: auto; 10 | text-align: left; 11 | text-align: start; 12 | text-decoration: none; 13 | text-shadow: none; 14 | text-transform: none; 15 | white-space: normal; 16 | word-break: normal; 17 | word-spacing: normal; 18 | word-wrap: normal; 19 | font-size: $tooltip-font-size; 20 | opacity: 0; 21 | z-index: 3000; 22 | 23 | &.in { 24 | opacity: 1; 25 | } 26 | 27 | &.top { 28 | margin-top: -$tooltip-arrow-width; 29 | padding: $tooltip-arrow-height 0; 30 | 31 | .tooltip-arrow { 32 | bottom: 0; 33 | left: 50%; 34 | margin-left: -$tooltip-arrow-width; 35 | border-width: $tooltip-arrow-height $tooltip-arrow-width 0; 36 | border-top-color: $tooltip-color; 37 | } 38 | } 39 | 40 | &.right { 41 | margin-left: $tooltip-arrow-width; 42 | padding: 0 $tooltip-arrow-height; 43 | 44 | .tooltip-arrow { 45 | top: 50%; 46 | left: 0; 47 | margin-top: -$tooltip-arrow-width; 48 | border-width: $tooltip-arrow-width $tooltip-arrow-height $tooltip-arrow-width 0; 49 | border-right-color: $tooltip-color; 50 | } 51 | } 52 | 53 | &.bottom { 54 | margin-top: $tooltip-arrow-width; 55 | padding: $tooltip-arrow-height 0; 56 | 57 | .tooltip-arrow { 58 | top: 0; 59 | left: 50%; 60 | margin-left: -$tooltip-arrow-width; 61 | border-width: 0 $tooltip-arrow-width $tooltip-arrow-height; 62 | border-bottom-color: $tooltip-color; 63 | } 64 | } 65 | 66 | &.left { 67 | margin-left: -$tooltip-arrow-width; 68 | padding: 0 $tooltip-arrow-height; 69 | 70 | .tooltip-arrow { 71 | top: 50%; 72 | right: 0; 73 | margin-top: -$tooltip-arrow-width; 74 | border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-height; 75 | border-left-color: $tooltip-color; 76 | } 77 | } 78 | } 79 | 80 | .tooltip-inner { 81 | max-width: 200px; 82 | padding: $tooltip-padding-vertical $tooltip-padding-horizontal; 83 | color: #ffffff; 84 | text-align: center; 85 | background-color: $tooltip-color; 86 | border-radius: 2px; 87 | color: #555!important; 88 | font-size: 13px; 89 | } 90 | 91 | .tooltip-arrow { 92 | position: absolute; 93 | width: 0; 94 | height: 0; 95 | border-color: transparent; 96 | border-style: solid; 97 | } 98 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/layout/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/layout/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/sass/layout/_content.scss: -------------------------------------------------------------------------------- 1 | .flex-container { 2 | display: flex; 3 | -webkit-justify-content: space-around; 4 | flex-grow: 1; 5 | flex-shrink: 1; 6 | position: relative; 7 | } 8 | 9 | .flex-expand { 10 | background-color: #000; 11 | color: #fff; 12 | flex: 1; 13 | display: flex; 14 | flex-direction: column; 15 | overflow: hidden; 16 | flex: 1; 17 | } 18 | 19 | .app-fullscreen { 20 | display: flex; 21 | flex-direction: column; 22 | height: 100%; 23 | flex: 1; 24 | position: absolute; 25 | top: 0; 26 | bottom: 0; 27 | right: 0; 28 | left: 0; 29 | } 30 | 31 | 32 | /* * * * 33 | * Containers 34 | * * * */ 35 | .content-scrollable { 36 | overflow-y: auto; 37 | } 38 | 39 | .container-fluid { 40 | position: relative; 41 | } 42 | 43 | .container { 44 | position: relative; 45 | margin: 0 auto; 46 | /* Widths/breakpoints should be figured out later and assigned to variables */ 47 | max-width: 1000px; 48 | } 49 | 50 | /* Style for this specific application */ 51 | .container-fluid { 52 | height: 300px; 53 | } -------------------------------------------------------------------------------- /styleguide/app/assets/sass/layout/_typography.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Typography 3 | * * * */ 4 | body { 5 | font-size: $font-size-body; 6 | line-height: $body-line-height; 7 | color: $body-font-color; 8 | font-family: $body-font-family; 9 | font-weight: $body-font-weight; 10 | } 11 | 12 | h1, .h1, .text-h1 { 13 | font-size: $font-size-h1; 14 | } 15 | 16 | h2, .h2, .text-h2 { 17 | font-size: $font-size-h2; 18 | } 19 | 20 | h3, .h3, .text-h3 { 21 | font-size: $font-size-h3; 22 | } 23 | 24 | h4, .h4, .text-h4 { 25 | font-size: $font-size-h4; 26 | } 27 | 28 | h5, .h5, .text-h5 { 29 | font-size: $font-size-h5; 30 | } 31 | 32 | h6, .h6, .text-h6 { 33 | font-size: $font-size-h6; 34 | } 35 | 36 | h1, h2, h3, h4, h5, h6, 37 | .h1, .h2, .h3, .h4, .h5, .h6 { 38 | line-height: $heading-line-height; 39 | color: $heading-font-color; 40 | font-family: $heading-font-family; 41 | margin-top: $heading-margin-top; 42 | margin-bottom: $heading-margin-bottom; 43 | font-weight: $heading-font-weight; 44 | } 45 | 46 | p { 47 | margin-top: 0; 48 | margin-bottom: $paragraph-margin; 49 | } 50 | 51 | small, .small { 52 | font-size: 85%; 53 | } 54 | 55 | em { 56 | font-style: italic; 57 | } 58 | 59 | strong { 60 | font-weight: bold; 61 | } 62 | 63 | ul, ol, dt { 64 | margin-top: 0; 65 | margin-bottom: $paragraph-margin; 66 | } 67 | 68 | pre, code { 69 | font-family: $monospace-font-family; 70 | } 71 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/main.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Utilities 3 | * No css should output from these 4 | * * * */ 5 | @import 6 | 'utils/functions', 7 | 'utils/variables', 8 | 'utils/mixins', 9 | 'utils/clearfix'; 10 | 11 | @import url('../fonts/fontello/css/mantle.css'); 12 | 13 | /* * * * 14 | * Vendors imports 15 | * * * */ 16 | @import 17 | 'vendors/snippet_components'; 18 | 19 | /* * * * 20 | * Base boilerplate styling 21 | * * * */ 22 | @import 23 | 'base/base'; 24 | /* * * * 25 | * Layout and overall structure 26 | * * * */ 27 | // @import 28 | // 'layout/typography'; 29 | /* * * * 30 | * Components styling 31 | * * * */ 32 | @import 33 | 'components/button', 34 | 'components/dropdown', 35 | 'components/alert', 36 | 'components/slider', 37 | 'components/tabs', 38 | 'components/form', 39 | 'components/tooltip'; 40 | 41 | /* * * * 42 | * Page specific styling 43 | * * * */ 44 | // @import Placeholder 45 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/pages/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/pages/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/sass/utils/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/utils/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/sass/utils/_clearfix.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Clearfix 3 | * * * */ 4 | .clearfix { 5 | @include clearfix; 6 | } 7 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/utils/_functions.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Exponential 3 | * Calculates mathematical exponent, like 3 to the 2nd power 4 | * Useage: exponential(3,2) 5 | * * * */ 6 | @function exponential($number, $exponent) { 7 | $value: 1; 8 | 9 | @if $exponent > 0 { 10 | @for $i from 1 through $exponent { 11 | $value: $value * $number; 12 | } 13 | } 14 | 15 | @return $value; 16 | } 17 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/utils/_utilities.scss: -------------------------------------------------------------------------------- 1 | /* * * * 2 | * Spacing 3 | * * * */ 4 | 5 | @include generate-padding; 6 | @include generate-margin; 7 | 8 | /* * * * 9 | * Font & Text 10 | * * * */ 11 | 12 | .font-normal { 13 | font-weight: normal; 14 | } 15 | 16 | .font-bold { 17 | font-weight: bold; 18 | } 19 | 20 | .font-italic { 21 | font-style: italic; 22 | } 23 | 24 | .text-uppercase { 25 | text-transform: uppercase; 26 | } 27 | 28 | .text-lowercase { 29 | text-transform: lowercase; 30 | } 31 | 32 | .text-capitalize { 33 | text-transform: capitalize; 34 | } 35 | 36 | .text-center { 37 | text-align: center 38 | } 39 | 40 | .text-left { 41 | text-align: left; 42 | } 43 | 44 | .text-right { 45 | text-align: right; 46 | } 47 | 48 | /* * * * 49 | * Color 50 | * * * */ 51 | 52 | .color-white { 53 | color: #fff; 54 | } 55 | 56 | .color-primary { 57 | color: $brand-primary; 58 | } 59 | 60 | .color-secondary { 61 | color: $brand-secondary; 62 | } 63 | 64 | .color-warning { 65 | color: $brand-warning; 66 | } 67 | 68 | .color-danger { 69 | color: $brand-danger; 70 | } 71 | 72 | .background-white { 73 | background-color: #fff; 74 | } 75 | 76 | .background-primary { 77 | background-color: $brand-primary; 78 | } 79 | 80 | .background-secondary { 81 | background-color: $brand-secondary; 82 | } 83 | 84 | .background-warning { 85 | background-color: $brand-warning; 86 | } 87 | 88 | .background-danger { 89 | background-color: $brand-danger; 90 | } 91 | 92 | /* * * * 93 | * Layout 94 | * * * */ 95 | 96 | .float-left { 97 | float: left; 98 | } 99 | 100 | .float-right { 101 | float: right; 102 | } 103 | 104 | .hidden { 105 | display: none; 106 | } 107 | 108 | .flex-expand { 109 | background-color: #efefef; 110 | } 111 | -------------------------------------------------------------------------------- /styleguide/app/assets/sass/vendors/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/assets/sass/vendors/.gitkeep -------------------------------------------------------------------------------- /styleguide/app/assets/snippet/style.css: -------------------------------------------------------------------------------- 1 | /* Minor overrides of CR styles for this site to display outside the framework */ 2 | body{ 3 | color:#5d6165; 4 | padding:0 10px 100px 10px; 5 | min-width:200px; 6 | } 7 | h1{ 8 | font-size: 26px; 9 | } 10 | .sidebar-content{ 11 | margin-top:0; 12 | } 13 | section{ 14 | margin-left:5px; 15 | } 16 | /* Style wrapper of raw HTML/JavaScript */ 17 | pre{ 18 | white-space: pre-wrap; 19 | white-space: -moz-pre-wrap; 20 | word-wrap: break-word; 21 | } 22 | .copyBlocks{ 23 | background:#fafafa; 24 | border: 1px solid #888; 25 | box-shadow: inset 1px 1px 2px rgba(0,0,0,0.25); 26 | padding:10px; 27 | display:none; 28 | } 29 | .my-button .button{ 30 | width: 150px; 31 | } 32 | .und{ 33 | text-decoration: underline; 34 | } -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(1).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(2).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(3).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(4).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(5).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm(6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm(6).png -------------------------------------------------------------------------------- /styleguide/app/cr_files/icon_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/styleguide/app/cr_files/icon_sm.png -------------------------------------------------------------------------------- /styleguide/grunt/aliases.yaml: -------------------------------------------------------------------------------- 1 | default: 2 | - 'sass' 3 | - 'postcss' 4 | - 'browserSync' 5 | - 'watch' -------------------------------------------------------------------------------- /styleguide/grunt/browserSync.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dev: { 3 | bsFiles: { 4 | src : [ 5 | 'app/**/*.css', 6 | 'app/**/*.html' 7 | ] 8 | }, 9 | options: { 10 | watchTask: true, 11 | server: './app' 12 | } 13 | } 14 | }; -------------------------------------------------------------------------------- /styleguide/grunt/concurrent.js: -------------------------------------------------------------------------------- 1 | // This file goes with grunt-concurrent. Not in use 2 | module.exports = { 3 | first: [ 4 | 'sass', 5 | 'postcss' 6 | ], 7 | second: [ 8 | 'watch', 9 | 'browserSync' 10 | ] 11 | }; -------------------------------------------------------------------------------- /styleguide/grunt/postcss.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: { 3 | map: false, 4 | processors: [ 5 | require('autoprefixer')({browsers: ['last 2 versions']}), 6 | require('cssnano')({ 7 | 'safe': true 8 | }) // minify the result 9 | ], 10 | }, 11 | dist: { 12 | src: 'app/assets/css/*.css' 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /styleguide/grunt/sass.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | options: { 3 | sourceMap: true 4 | }, 5 | dev: { 6 | files: { 7 | 'app/assets/css/main.css': 'app/assets/sass/main.scss' 8 | } 9 | } 10 | }; -------------------------------------------------------------------------------- /styleguide/grunt/watch.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | script: { 3 | files: ['app/**/*.js'], 4 | options: { 5 | spawn: false, 6 | } 7 | }, 8 | 9 | css: { 10 | files: ['app/**/*.scss'], 11 | tasks: ['sass', 'postcss'], 12 | options: { 13 | spawn: false, 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /styleguide/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "maplication", 3 | "version": "0.1.0", 4 | "description": "Azavea's front end framework for GIS applications", 5 | "devDependencies": { 6 | "autoprefixer": "^6.3.6", 7 | "cssnano": "^3.5.2", 8 | "grunt": "^0.4.5", 9 | "grunt-browser-sync": "^2.2.0", 10 | "grunt-contrib-watch": "^1.0.0", 11 | "grunt-newer": "^1.2.0", 12 | "grunt-postcss": "^0.8.0", 13 | "grunt-sass": "^1.1.0", 14 | "load-grunt-config": "^0.19.1", 15 | "load-grunt-tasks": "^3.5.0", 16 | "time-grunt": "^1.3.0" 17 | }, 18 | "dependencies": { 19 | "@frctl/fractal": "^1.0.11" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "jasmine", 3 | "test_page": "src/GeositeFramework/js/tests/specRunner.html" 4 | } 5 | -------------------------------------------------------------------------------- /tools/JsTestTools/jstdServer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script was adapted from server.sh in https://github.com/ibolmo/jasmine-jstd-adapter 3 | while getopts "j:p:" flag 4 | do 5 | if [ $flag == "j" ]; then 6 | JSTD=$OPTARG 7 | elif [ $flag == "p" ]; then 8 | PORT=$OPTARG 9 | fi 10 | done 11 | 12 | if [ -z "$PORT" ]; then 13 | PORT=9876 14 | fi 15 | 16 | if [ -z "$JSTD" ]; then 17 | JSTD=`ls jstestdriver/[jJ]s[tT]est[dD]river-1.3.1.jar` 18 | fi 19 | echo "Using $JSTD" 20 | echo "Launching JsTestDriver server on port $PORT" 21 | java -jar $JSTD --port $PORT 22 | 23 | -------------------------------------------------------------------------------- /tools/JsTestTools/jstestdriver/JsTestDriver-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/jstestdriver/JsTestDriver-1.3.1.jar -------------------------------------------------------------------------------- /tools/JsTestTools/jstestdriver/why_1.3.1_and_not_1.3.2.txt: -------------------------------------------------------------------------------- 1 | There is a bug in version 1.3.2 that prevents using relative paths in the jstestdriver.conf file 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/azavea-jasmine/azavea.jasmine.matchers.js: -------------------------------------------------------------------------------- 1 | beforeEach(function() { 2 | this.addMatchers({ 3 | toBeAFunction: function() { 4 | return ((typeof this.actual) === 'function'); 5 | }, 6 | toBeADate: function() { 7 | return (this.actual.constructor === (new Date).constructor); 8 | } 9 | }); 10 | }); 11 | 12 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine-jquery/source.txt: -------------------------------------------------------------------------------- 1 | https://github.com/velesin/jasmine-jquery 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine-jstd-adapter/source.txt: -------------------------------------------------------------------------------- 1 | https://github.com/ibolmo/jasmine-jstd-adapter 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine-reporters/jasmine.console_reporter.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | if (! jasmine) { 4 | throw new Exception("jasmine library does not exist in global namespace!"); 5 | } 6 | 7 | /** 8 | * Basic reporter that outputs spec results to the browser console. 9 | * Useful if you need to test an html page and don't want the TrivialReporter 10 | * markup mucking things up. 11 | * 12 | * Usage: 13 | * 14 | * jasmine.getEnv().addReporter(new jasmine.ConsoleReporter()); 15 | * jasmine.getEnv().execute(); 16 | */ 17 | var ConsoleReporter = function() { 18 | this.started = false; 19 | this.finished = false; 20 | }; 21 | 22 | ConsoleReporter.prototype = { 23 | reportRunnerResults: function(runner) { 24 | this.finished = true; 25 | this.log("Runner Finished."); 26 | }, 27 | 28 | reportRunnerStarting: function(runner) { 29 | this.started = true; 30 | this.log("Runner Started."); 31 | }, 32 | 33 | reportSpecResults: function(spec) { 34 | var resultText = "Failed."; 35 | 36 | if (spec.results().passed()) { 37 | resultText = "Passed."; 38 | } 39 | 40 | this.log(resultText); 41 | }, 42 | 43 | reportSpecStarting: function(spec) { 44 | this.log(spec.suite.description + ' : ' + spec.description + ' ... '); 45 | }, 46 | 47 | reportSuiteResults: function(suite) { 48 | var results = suite.results(); 49 | 50 | this.log(suite.description + ": " + results.passedCount + " of " + results.totalCount + " passed."); 51 | }, 52 | 53 | log: function(str) { 54 | /* 55 | var console = jasmine.getGlobal().console; 56 | 57 | if (console && console.log) { 58 | console.log(str); 59 | } 60 | */ 61 | console.log(str); 62 | } 63 | }; 64 | 65 | // export public 66 | jasmine.ConsoleReporter = ConsoleReporter; 67 | })(); -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine-reporters/source.txt: -------------------------------------------------------------------------------- 1 | https://github.com/larrymyers/jasmine-reporters 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine/MIT.LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2011 Pivotal Labs 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/jasmine/source.txt: -------------------------------------------------------------------------------- 1 | http://pivotal.github.com/jasmine/download.html 2 | 3 | http://pivotal.github.com/jasmine/ 4 | https://github.com/pivotal/jasmine 5 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/templates/jsTestDriver.conf.template: -------------------------------------------------------------------------------- 1 | server: http://localhost:9876 2 | 3 | load: 4 | # load library files 5 | - lib/jquery/jquery-1.6.1.min.js 6 | 7 | # load test tools 8 | - lib/jasmine/jasmine.js 9 | - lib/jasmine/jasmine-html.js 10 | - lib/jasmine-jstd-adapter/JasmineAdapter.js 11 | - lib/jasmine-jquery/jasmine-jquery-1.2.0.js 12 | - lib/jasmine-reporters/jasmine.junit_reporter.js 13 | - lib/azavea-jasmine/azavea.jasmine.matchers.js 14 | 15 | # load application source files 16 | 17 | # load test spec files 18 | -------------------------------------------------------------------------------- /tools/JsTestTools/lib/templates/specRunner.html.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test Runner 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs-testrunner.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | if (phantom.args.length === 0) { 3 | console.log("Simple JasmineBDD test runner for phantom.js"); 4 | console.log("Usage: phantomjs-testrunner.js url_to_runner.html"); 5 | console.log("Accepts http:// and file:// urls"); 6 | console.log(""); 7 | console.log("NOTE: This script depends on jasmine.TrivialReporter being used\non the page, for the DOM elements it creates.\n"); 8 | phantom.exit(); 9 | } else { 10 | var address = phantom.args[0]; 11 | phantom.state = "run-jasminebdd"; 12 | //console.log('Loading ' + address); 13 | phantom.open(address); 14 | } 15 | } else { 16 | if (phantom.loadStatus === 'success') { 17 | //Just b/c phantom thinks the page has loaded doesn't necessarily mean it has, so we check periodically 18 | var doneYet = function () { 19 | var finishedDiv = document.getElementsByClassName("finished-at")[0]; 20 | var _setInterval = jasmine.Clock.real.setInterval; 21 | if (finishedDiv) { 22 | _setInterval(function(){ 23 | if (finishedDiv.innerHTML.length) { 24 | var results = document.getElementsByClassName("description")[0].innerHTML.match(/(\d+) spec.* (\d+) failure.*/); 25 | var specs = Number(results[1]); 26 | var failures = Number(results[2]); 27 | console.log(""); // insert blank line 28 | if (failures > 0) { 29 | console.error("FAILURE: " + results[0]); 30 | phantom.exit(1); 31 | } 32 | else { 33 | console.log("SUCCESS: " + results[0]); 34 | phantom.exit(0); 35 | } 36 | } 37 | }, 100); 38 | } 39 | else { 40 | setTimeout(function () { doneYet(); }, 1000); 41 | } 42 | }; 43 | 44 | doneYet(); 45 | } else { 46 | console.log("Failed to load the specified url"); 47 | phantom.exit(1); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pro.user* 3 | *.xcodeproj 4 | Makefile* 5 | bin/ 6 | *~ 7 | *.moc 8 | moc_* 9 | qrc_* 10 | *.o 11 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/ChangeLog: -------------------------------------------------------------------------------- 1 | 2011-04-27: Version 1.1.0 2 | 3 | Fixed the script loading to use UTF-8 encoding (Yasuhiro Matsumoto). 4 | 5 | Added check for system proxy setting (Yasuhiro Matsumoto). 6 | 7 | Fixed building with Cygwin and Qt 4.5 (John Dalton). 8 | 9 | Added a new example: driver for QUnit tests (Łukasz Korecki). 10 | 11 | Fixed issue #20: problem with JPG transparent color (Alessandro Portale). 12 | 13 | Fixed issue #9: ignore first line starting with #! (Matthias, aka fourplusone). 14 | 15 | Fixed issue #7: support for file upload for form submission (Matthias, aka fourplusone). 16 | 17 | Fixed issue #35: support for disabling images loading (Ariya Hidayat). 18 | 19 | Fixed issue #14: enable or disable plugins (Ariya Hidayat). 20 | 21 | Added a new example: using Canvas to produce the color wheel (Ariya Hidayat). 22 | 23 | Added support for rasterizing as GIF image (Ariya Hidayat). 24 | 25 | Added support for CoffeeScript (Ariya Hidayat). 26 | 27 | Fixed issue #19: option for setting the proxy (Clint Berry, Ariya Hidayat). 28 | 29 | Python implementation using PyQt (James Roe). 30 | 31 | Fixed issue #17: Specify paper size for PDF export (Alessandro Portale). 32 | 33 | Fixed issue #60: Win32 and OS/2 icon files (Salvador Parra Camacho). 34 | 35 | Added clipping rectangle to the render function (Wouter de Bie). 36 | 37 | Added an example on sychronous waiting (Gabor Torok). 38 | 39 | Added command line option to use disk cache (Jon Turner). 40 | 41 | Added text extracting example (Weston Ruter). 42 | 43 | Fixed issue #93: Build with Qt < 4.7 (Ariya Hidayat). 44 | 45 | Ported all examples to CoffeeScript (Robert Gieseke). 46 | 47 | 2011-01-17: Version 1.0.0 48 | 49 | Initial launch. 50 | 51 | The API is centralized at the 'phantom' object (as child of 52 | window object) which has the properties: args, content, 53 | loadStatus, state, userAgent, version, viewportSize, and 54 | the following functions: exit, open, render, sleep. 55 | 56 | Several examples are included, among others: web page rasterizer, 57 | weather service, headless test framework driver, and many others. 58 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | * Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | * Redistributions in binary form must reproduce the above copyright 7 | notice, this list of conditions and the following disclaimer in the 8 | documentation and/or other materials provided with the distribution. 9 | * Neither the name of the nor the 10 | names of its contributors may be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/README.md: -------------------------------------------------------------------------------- 1 | PhantomJS is a minimalistic, headless, WebKit-based JavaScript-driven tool. 2 | 3 | It has native (and high performant) support for DOM handling, CSS selector, 4 | JSON, Canvas, and SVG. 5 | 6 | Read the [announcement blog post](http://goo.gl/sZfM7). 7 | 8 | PhantomJS runs on Linux, Windows, and Mac OS X. Refer to the 9 | [build instructions](http://code.google.com/p/phantomjs/wiki/BuildInstructions) 10 | for details. 11 | 12 | See also [quick start guide](http://code.google.com/p/phantomjs/wiki/QuickStart) 13 | and more [advanced examples](http://code.google.com/p/phantomjs/wiki/ServiceIntegration) 14 | which show various PhantomJS scripts, covering: 15 | 16 | * getting driving direction 17 | * showing weather forecast conditions 18 | * finding pizza in New York 19 | * looking up approximate location based on IP address 20 | * pulling the list of seasonal food 21 | * running regression tests from command line 22 | * producing PDF version of a Wikipedia article 23 | * rasterizing SVG to image 24 | 25 | Do not forget to consult the concise [API Reference](http://code.google.com/p/phantomjs/wiki/Interface). 26 | 27 | If you want to contribute, please read the [Contribution 28 | Guide](http://code.google.com/p/phantomjs/wiki/ContributionGuide). 29 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/arguments.coffee: -------------------------------------------------------------------------------- 1 | if phantom.args.length is 0 2 | console.log 'Try to pass some args when invoking this script!' 3 | else 4 | for arg, i in phantom.args 5 | console.log i + ': ' + arg 6 | phantom.exit() 7 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/arguments.js: -------------------------------------------------------------------------------- 1 | if (phantom.args.length === 0) { 2 | console.log('Try to pass some args when invoking this script!'); 3 | } else { 4 | phantom.args.forEach(function (arg, i) { 5 | console.log(i + ': ' + arg); 6 | }); 7 | } 8 | phantom.exit(); 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/colorwheel.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | phantom.state = 1 3 | phantom.viewportSize = { width: 400, height : 400 } 4 | phantom.content = '' + 5 | '' 6 | else 7 | el = document.getElementById 'surface' 8 | context = el.getContext '2d' 9 | width = window.innerWidth 10 | height = window.innerHeight 11 | cx = width / 2 12 | cy = height / 2 13 | radius = width / 2.3 14 | i = 0 15 | 16 | el.width = width 17 | el.height = height 18 | imageData = context.createImageData(width, height) 19 | pixels = imageData.data 20 | 21 | for y in [0...height] 22 | for x in [0...width] 23 | i = i + 4 24 | rx = x - cx 25 | ry = y - cy 26 | d = rx * rx + ry * ry 27 | if d < radius * radius 28 | hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI) 29 | sat = Math.sqrt(d) / radius 30 | g = Math.floor(hue) 31 | f = hue - g 32 | u = 255 * (1 - sat) 33 | v = 255 * (1 - sat * f) 34 | w = 255 * (1 - sat * (1 - f)) 35 | pixels[i] = [255, v, u, u, w, 255, 255][g] 36 | pixels[i + 1] = [w, 255, 255, v, u, u, w][g] 37 | pixels[i + 2] = [u, u, w, 255, 255, v, u][g] 38 | pixels[i + 3] = 255 39 | 40 | context.putImageData imageData, 0, 0 41 | document.body.style.backgroundColor = 'white' 42 | document.body.style.margin = '0px' 43 | 44 | phantom.render 'colorwheel.png' 45 | phantom.exit() 46 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/colorwheel.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | phantom.state = 1; 3 | phantom.viewportSize = { width: 400, height : 400 }; 4 | phantom.content = '' + 5 | ''; 6 | } else { 7 | var el = document.getElementById('surface'), 8 | context = el.getContext('2d'), 9 | width = window.innerWidth, 10 | height = window.innerHeight, 11 | cx = width / 2, 12 | cy = height / 2, 13 | radius = width / 2.3, 14 | imageData, 15 | pixels, 16 | hue, sat, value, 17 | i = 0, x, y, rx, ry, d, 18 | f, g, p, u, v, w, rgb; 19 | 20 | el.width = width; 21 | el.height = height; 22 | imageData = context.createImageData(width, height); 23 | pixels = imageData.data; 24 | 25 | for (y = 0; y < height; y = y + 1) { 26 | for (x = 0; x < width; x = x + 1, i = i + 4) { 27 | rx = x - cx; 28 | ry = y - cy; 29 | d = rx * rx + ry * ry; 30 | if (d < radius * radius) { 31 | hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI); 32 | sat = Math.sqrt(d) / radius; 33 | g = Math.floor(hue); 34 | f = hue - g; 35 | u = 255 * (1 - sat); 36 | v = 255 * (1 - sat * f); 37 | w = 255 * (1 - sat * (1 - f)); 38 | pixels[i] = [255, v, u, u, w, 255, 255][g]; 39 | pixels[i + 1] = [w, 255, 255, v, u, u, w][g]; 40 | pixels[i + 2] = [u, u, w, 255, 255, v, u][g]; 41 | pixels[i + 3] = 255; 42 | } 43 | } 44 | } 45 | 46 | context.putImageData(imageData, 0, 0); 47 | document.body.style.backgroundColor = 'white'; 48 | document.body.style.margin = '0px'; 49 | 50 | phantom.render('colorwheel.png'); 51 | phantom.exit(); 52 | } 53 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/countdown.coffee: -------------------------------------------------------------------------------- 1 | t = 10 2 | while t > 0 3 | console.log t 4 | phantom.sleep 1000 5 | t = t - 1 6 | 7 | console.log 'BLAST OFF' 8 | phantom.exit() 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/countdown.js: -------------------------------------------------------------------------------- 1 | var t = 10; 2 | while (t > 0) { 3 | console.log(t); 4 | phantom.sleep(1000); 5 | t = t - 1; 6 | } 7 | console.log('BLAST OFF'); 8 | phantom.exit(); 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/cycle_multiple_urls.js: -------------------------------------------------------------------------------- 1 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | Cycle array of URLs and process with phantom.js 3 | Adds Array.prototype.forEachWebPage() iterator. 4 | 5 | EXAMPLE: 6 | Save screenshots. Command line: 7 | phantomjs phantom_js_url_cycle.js ./screenshots 8 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 | 10 | [ 11 | 12 | 'www.google.com', 13 | 'www.bbc.co.uk', 14 | 'www.phantomjs.org' 15 | 16 | ].forEachWebPage(function (url) { 17 | var out_dir = phantom.args[0] || '.'; 18 | var file_name = [out_dir, url + '.png'].join('/'); // ./screenshots/www.google.com.png 19 | phantom.render(file_name); 20 | console.log('Generated ' + file_name); 21 | }); 22 | 23 | -------------------------- */ 24 | var UrlCycle = (function () { 25 | 26 | function extend (target, source) { 27 | for(var i in source) { 28 | target[i] = source[i]; 29 | } 30 | } 31 | 32 | var prot = 'http://', urls, opts = {width: 800, height: 600}; 33 | 34 | function cycle (urls, o, callback) { 35 | if(phantom.state.length === 0){ // first pass 36 | urls = urls; 37 | extend(opts, o || {}); 38 | phantom.viewportSize = { width: opts.width, height: opts.height }; 39 | phantom.state = 0; 40 | phantom.userAgent = 'Phantom.js bot'; 41 | phantom.open(prot + urls[phantom.state]); 42 | } else { // page open 43 | 44 | callback(urls[phantom.state]); 45 | 46 | if(next_url = urls[++phantom.state]) { 47 | console.log('opening '+next_url) 48 | phantom.open(prot+next_url); 49 | } else { 50 | console.log('Done. Bye!') 51 | phantom.exit(); 52 | } 53 | } 54 | } 55 | 56 | Array.prototype.forEachWebPage = function (callback, opts) { 57 | cycle(this, opts, callback); 58 | } 59 | 60 | return { 61 | cycle: cycle 62 | }; 63 | 64 | })(); -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/direction.coffee: -------------------------------------------------------------------------------- 1 | # Get driving direction using Google Directions API. 2 | 3 | if phantom.state.length is 0 4 | if phantom.args.length < 2 5 | console.log 'Usage: direction.js origin destination' 6 | console.log 'Example: direction.js "San Diego" "Palo Alto"' 7 | phantom.exit(1) 8 | origin = phantom.args[0] 9 | dest = phantom.args[1] 10 | phantom.state = origin + ' to ' + dest 11 | phantom.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin + 12 | '&destination=' + dest + '&units=imperial&mode=driving&sensor=false')) 13 | else 14 | if phantom.loadStatus is 'fail' 15 | console.log 'Unable to access network' 16 | else 17 | steps = phantom.content.match(/(.*)<\/html_instructions>/ig) 18 | if not steps 19 | console.log 'No data available for ' + phantom.state 20 | else 21 | for ins in steps 22 | ins = ins.replace(/\</ig, '<').replace(/\>/ig, '>') 23 | ins = ins.replace(/\
/g, '') 25 | console.log(ins) 26 | console.log '' 27 | console.log phantom.content.match(/.*<\/copyrights>/ig).join('').replace(/<.*?>/g, '') 28 | phantom.exit() 29 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/direction.js: -------------------------------------------------------------------------------- 1 | // Get driving direction using Google Directions API. 2 | 3 | if (phantom.state.length === 0) { 4 | var origin, dest; 5 | if (phantom.args.length < 2) { 6 | console.log('Usage: direction.js origin destination'); 7 | console.log('Example: direction.js "San Diego" "Palo Alto"'); 8 | phantom.exit(1); 9 | } 10 | origin = phantom.args[0]; 11 | dest = phantom.args[1]; 12 | phantom.state = origin + ' to ' + dest; 13 | phantom.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin=' + origin + 14 | '&destination=' + dest + '&units=imperial&mode=driving&sensor=false')); 15 | } else { 16 | if (phantom.loadStatus === 'fail') { 17 | console.log('Unable to access network'); 18 | } else { 19 | var steps = phantom.content.match(/(.*)<\/html_instructions>/ig); 20 | if (steps == null) { 21 | console.log('No data available for ' + phantom.state); 22 | } else { 23 | steps.forEach(function (ins) { 24 | ins = ins.replace(/\</ig, '<').replace(/\>/ig, '>'); 25 | ins = ins.replace(/\
/g, ''); 27 | console.log(ins); 28 | }); 29 | console.log(''); 30 | console.log(phantom.content.match(/.*<\/copyrights>/ig).join('').replace(/<.*?>/g, '')); 31 | } 32 | } 33 | phantom.exit(); 34 | } 35 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/fibo.coffee: -------------------------------------------------------------------------------- 1 | fibs = [0, 1] 2 | f = -> 3 | console.log fibs[fibs.length - 1] 4 | fibs.push fibs[fibs.length - 1] + fibs[fibs.length - 2] 5 | if fibs.length > 10 6 | window.clearInterval ticker 7 | phantom.exit() 8 | ticker = window.setInterval(f, 300) 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/fibo.js: -------------------------------------------------------------------------------- 1 | var fibs = [0, 1]; 2 | var ticker = window.setInterval(function () { 3 | console.log(fibs[fibs.length - 1]); 4 | fibs.push(fibs[fibs.length - 1] + fibs[fibs.length - 2]); 5 | if (fibs.length > 10) { 6 | window.clearInterval(ticker); 7 | phantom.exit(); 8 | } 9 | }, 300); 10 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/follow.coffee: -------------------------------------------------------------------------------- 1 | # List following and followers from several accounts 2 | 3 | if phantom.state.length == 0 4 | phantom.state = [ 5 | 'sencha' 6 | 'aconran' 7 | 'ariyahidayat' 8 | 'darrellmeyer' 9 | 'DavidKaneda' 10 | 'DmitryBaranovsk' 11 | 'donovanerba' 12 | 'edspencer' 13 | 'helder_correia' 14 | 'jamespearce' 15 | 'jamieavins' 16 | 'jarrednicholls' 17 | 'jayrobinson' 18 | 'lojjic' 19 | 'mmullany' 20 | 'philogb' 21 | 'rdougan' 22 | 'tmaintz' 23 | 'whereisthysting' 24 | ].join ':' 25 | phantom.open 'http://mobile.twitter.com/sencha' 26 | else 27 | users = phantom.state.split ':' 28 | id = users[0] 29 | next = users[1] 30 | data = document.querySelector 'div.timeline-following' 31 | phantom.state = users.slice(1).join ':' 32 | console.log id + ': ' + data.innerText 33 | if next 34 | phantom.open 'http://mobile.twitter.com/' + next 35 | else 36 | phantom.exit 1 37 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/follow.js: -------------------------------------------------------------------------------- 1 | // List following and followers from several accounts 2 | 3 | if (phantom.state.length === 0) { 4 | phantom.state = ['sencha', 5 | 'aconran', 6 | 'ariyahidayat', 7 | 'darrellmeyer', 8 | 'DavidKaneda', 9 | 'DmitryBaranovsk', 10 | 'donovanerba', 11 | 'edspencer', 12 | 'helder_correia', 13 | 'jamespearce', 14 | 'jamieavins', 15 | 'jarrednicholls', 16 | 'jayrobinson', 17 | 'lojjic', 18 | 'mmullany', 19 | 'philogb', 20 | 'rdougan', 21 | 'tmaintz', 22 | 'whereisthysting'].join(':'); 23 | phantom.open('http://mobile.twitter.com/sencha'); 24 | } else { 25 | var users = phantom.state.split(':'), 26 | id = users[0], 27 | next = users[1], 28 | data = document.querySelector('div.timeline-following'); 29 | phantom.state = users.slice(1).join(':'); 30 | console.log(id + ': ' + data.innerText); 31 | if (next) { 32 | phantom.open('http://mobile.twitter.com/' + next); 33 | } else { 34 | phantom.exit(); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/hello.coffee: -------------------------------------------------------------------------------- 1 | console.log 'Hello, world!' 2 | phantom.exit() 3 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/hello.js: -------------------------------------------------------------------------------- 1 | console.log('Hello, world!'); 2 | phantom.exit(); 3 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/ipgeocode.coffee: -------------------------------------------------------------------------------- 1 | # Give the estimated location based on the IP address. 2 | 3 | window.cb = (data) -> 4 | loc = data.city 5 | if data.region_name.length > 0 6 | loc = loc + ', ' + data.region_name 7 | console.log 'IP address: ' + data.ip 8 | console.log 'Estimated location: ' + loc 9 | phantom.exit() 10 | 11 | el = document.createElement 'script' 12 | el.src = 'http://freegeoip.net/json/?callback=window.cb' 13 | document.body.appendChild el 14 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/ipgeocode.js: -------------------------------------------------------------------------------- 1 | // Give the estimated location based on the IP address. 2 | 3 | cb = function (data) { 4 | var loc = data.city; 5 | if (data.region_name.length > 0) 6 | loc = loc + ', ' + data.region_name; 7 | console.log('IP address: ' + data.ip); 8 | console.log('Estimated location: ' + loc); 9 | phantom.exit(); 10 | }; 11 | 12 | var el = document.createElement('script'); 13 | el.src = 'http://freegeoip.net/json/?callback=cb'; 14 | document.body.appendChild(el); 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/loadspeed.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | if phantom.args.length is 0 3 | console.log 'Usage: loadspeed.js ' 4 | phantom.exit() 5 | else 6 | address = phantom.args[0] 7 | phantom.state = Date.now().toString() 8 | console.log 'Loading ' + address 9 | phantom.open(address) 10 | else 11 | elapsed = Date.now() - new Date().setTime(phantom.state) 12 | if phantom.loadStatus is 'success' 13 | console.log 'Page title is ' + document.title 14 | console.log 'Loading time ' + elapsed + ' msec' 15 | else 16 | console.log 'FAIL to load the address' 17 | phantom.exit() 18 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/loadspeed.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | if (phantom.args.length === 0) { 3 | console.log('Usage: loadspeed.js '); 4 | phantom.exit(); 5 | } else { 6 | var address = phantom.args[0]; 7 | phantom.state = Date.now().toString(); 8 | console.log('Loading ' + address); 9 | phantom.open(address); 10 | } 11 | } else { 12 | var elapsed = Date.now() - new Date().setTime(phantom.state); 13 | if (phantom.loadStatus === 'success') { 14 | console.log('Page title is ' + document.title); 15 | console.log('Loading time ' + elapsed + ' msec'); 16 | } else { 17 | console.log('FAIL to load the address'); 18 | } 19 | phantom.exit(); 20 | } 21 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/movies.coffee: -------------------------------------------------------------------------------- 1 | # List movies from kids-in-mind.com 2 | 3 | window.cbfunc = (data) -> 4 | globaldata = data 5 | list = data.query.results.movie 6 | for item in list 7 | console.log item.title + ' [' + item.rating.MPAA.content + ']' 8 | phantom.exit() 9 | 10 | el = document.createElement 'script' 11 | el.src = 12 | "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=window.cbfunc" 13 | document.body.appendChild el 14 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/movies.js: -------------------------------------------------------------------------------- 1 | // List movies from kids-in-mind.com 2 | 3 | var cbfunc = function (data) { 4 | globaldata= data; 5 | var list = data.query.results.movie; 6 | list.forEach(function (item) { 7 | console.log(item.title + ' [' + item.rating.MPAA.content + ']'); 8 | }); 9 | phantom.exit(); 10 | }; 11 | 12 | var el = document.createElement('script'); 13 | el.src = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20movies.kids-in-mind&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc'; 14 | document.body.appendChild(el); 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/pizza.coffee: -------------------------------------------------------------------------------- 1 | # Find pizza in New York using Google Local 2 | 3 | if phantom.state.length is 0 4 | phantom.state = 'pizza' 5 | phantom.open 'http://www.google.com/m/local?site=local&q=pizza+in+new+york' 6 | else 7 | list = document.querySelectorAll 'div.bf' 8 | for item in list 9 | console.log item.innerText 10 | phantom.exit() 11 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/pizza.js: -------------------------------------------------------------------------------- 1 | // Find pizza in New York using Google Local 2 | 3 | if (phantom.state.length === 0) { 4 | phantom.state = 'pizza'; 5 | phantom.open('http://www.google.com/m/local?site=local&q=pizza+in+new+york'); 6 | } else { 7 | var list = document.querySelectorAll('div.bf'); 8 | for (var i = 0; i < list.length; i++) { 9 | console.log(list[i].innerText); 10 | } 11 | phantom.exit(); 12 | } 13 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/rasterize.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | if phantom.args.length < 2 or phantom.args.length > 3 3 | console.log 'Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]' 4 | console.log ' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"' 5 | phantom.exit() 6 | else 7 | address = phantom.args[0] 8 | phantom.state = 'rasterize' 9 | phantom.viewportSize = { width: 600, height: 600 } 10 | if phantom.args.length is 3 and phantom.args[1].substr(-4) is ".pdf" 11 | size = phantom.args[2].split '*' 12 | if size.length is 2 13 | phantom.paperSize = { width: size[0], height: size[1], border: '0px' } 14 | else 15 | phantom.paperSize = { format: phantom.args[2], orientation: 'portrait', border: '1cm' } 16 | phantom.open(address) 17 | else 18 | output = phantom.args[1] 19 | phantom.sleep 200 20 | phantom.render output 21 | phantom.exit() 22 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/rasterize.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | if (phantom.args.length < 2 || phantom.args.length > 3) { 3 | console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]'); 4 | console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'); 5 | phantom.exit(); 6 | } else { 7 | var address = phantom.args[0]; 8 | phantom.state = 'rasterize'; 9 | phantom.viewportSize = { width: 600, height: 600 }; 10 | if (phantom.args.length === 3 && phantom.args[1].substr(-4) === ".pdf") { 11 | var size = phantom.args[2].split('*'); 12 | phantom.paperSize = size.length === 2 ? { width: size[0], height: size[1], border: '0px' } 13 | : { format: phantom.args[2], orientation: 'portrait', border: '1cm' }; 14 | } 15 | phantom.open(address); 16 | } 17 | } else { 18 | var output = phantom.args[1]; 19 | phantom.sleep(200); 20 | phantom.render(output); 21 | phantom.exit(); 22 | } 23 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/run-jasmine.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | if (phantom.args.length !== 1) { 3 | console.log('Usage: run-jasmine.js URL'); 4 | phantom.exit(); 5 | } else { 6 | phantom.state = 'run-jasmine'; 7 | phantom.open(phantom.args[0]); 8 | } 9 | } else { 10 | window.setInterval(function () { 11 | var list, el, desc, i, j; 12 | if (document.body.querySelector('.finished-at')) { 13 | console.log(document.body.querySelector('.description').innerText); 14 | list = document.body.querySelectorAll('div.jasmine_reporter > div.suite.failed'); 15 | for (i = 0; i < list.length; ++i) { 16 | el = list[i]; 17 | desc = el.querySelectorAll('.description'); 18 | console.log(''); 19 | for (j = 0; j < desc.length; ++j) { 20 | console.log(desc[j].innerText); 21 | } 22 | } 23 | phantom.exit(); 24 | } 25 | }, 100); 26 | } 27 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/run-qunit.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | if (phantom.args.length === 0 || phantom.args.length > 2) { 3 | console.log('Usage: run-qunit.js URL'); 4 | phantom.exit(); 5 | } else { 6 | phantom.state = 'run-qunit'; 7 | phantom.open(phantom.args[0]); 8 | } 9 | } else { 10 | setInterval(function() { 11 | var el = document.getElementById('qunit-testresult'); 12 | if (phantom.state !== 'finish') { 13 | if (el && el.innerText.match('completed')) { 14 | phantom.state = 'finish'; 15 | console.log(el.innerText); 16 | try { 17 | failed = el.getElementsByClassName('failed')[0].innerHTML; 18 | } catch (e) { 19 | } 20 | phantom.exit((parseInt(failed, 10) > 0) ? 1 : 0); 21 | } 22 | } 23 | }, 100); 24 | } 25 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/seasonfood.coffee: -------------------------------------------------------------------------------- 1 | # Show BBC seasonal food list. 2 | 3 | window.cbfunc = (data) -> 4 | list = data.query.results.results.result 5 | names = ['January', 'February', 'March', 6 | 'April', 'May', 'June', 7 | 'July', 'August', 'September', 8 | 'October', 'November', 'December'] 9 | for item in list 10 | console.log [item.name.replace(/\s/ig, ' '), ':', 11 | names[item.atItsBestUntil], 'to', 12 | names[item.atItsBestFrom]].join(' ') 13 | phantom.exit() 14 | 15 | el = document.createElement 'script' 16 | el.src = 'http://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20bbc.goodfood.seasonal%3B&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=window.cbfunc' 17 | document.body.appendChild el 18 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/seasonfood.js: -------------------------------------------------------------------------------- 1 | // Show BBC seasonal food list. 2 | 3 | var cbfunc = function (data) { 4 | var list = data.query.results.results.result, 5 | names = ['January', 'February', 'March', 6 | 'April', 'May', 'June', 7 | 'July', 'August', 'September', 8 | 'October', 'November', 'December']; 9 | list.forEach(function (item) { 10 | console.log([item.name.replace(/\s/ig, ' '), ':', 11 | names[item.atItsBestUntil], 'to', 12 | names[item.atItsBestFrom]].join(' ')); 13 | }); 14 | phantom.exit(); 15 | }; 16 | 17 | var el = document.createElement('script'); 18 | el.src = 'http://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20bbc.goodfood.seasonal%3B&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc'; 19 | document.body.appendChild(el); 20 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/technews.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | address = phantom.args[0] 3 | phantom.state = 'news' 4 | phantom.viewportSize = { width: 320, height: 480 } 5 | phantom.open 'http://news.google.com/news/i/section?&topic=t' 6 | else 7 | body = document.body 8 | body.style.backgroundColor = '#fff' 9 | body.querySelector('div#title-block').style.display = 'none' 10 | body.querySelector('form#edition-picker-form').parentElement.parentElement.style.display = 'none' 11 | phantom.sleep 500 12 | phantom.render 'technews.png' 13 | phantom.exit() 14 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/technews.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | var address = phantom.args[0]; 3 | phantom.state = 'news'; 4 | phantom.viewportSize = { width: 320, height: 480 }; 5 | phantom.open('http://news.google.com/news/i/section?&topic=t'); 6 | } else { 7 | var body = document.body; 8 | body.style.backgroundColor = '#fff'; 9 | body.querySelector('div#title-block').style.display = 'none'; 10 | body.querySelector('form#edition-picker-form').parentElement.parentElement.style.display = 'none'; 11 | phantom.sleep(500); 12 | phantom.render('technews.png'); 13 | phantom.exit(); 14 | } 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/tweets.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length == 0 2 | phantom.state = 'tweets' 3 | phantom.open 'http://mobile.twitter.com/sencha' 4 | else 5 | list = document.querySelectorAll 'span.status' 6 | for elem, index in list 7 | console.log((index + 1) + ': ' + elem.innerHTML.replace(/<.*?>/g, '')) 8 | phantom.exit() 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/tweets.js: -------------------------------------------------------------------------------- 1 | // Get twitter status from someone 2 | 3 | if (phantom.state.length === 0) { 4 | phantom.state = 'tweets'; 5 | phantom.open('http://mobile.twitter.com/sencha'); 6 | } else { 7 | var list = document.querySelectorAll('span.status'); 8 | for (var i = 0; i < list.length; ++i) { 9 | console.log((i + 1) + ': ' + list[i].innerHTML.replace(/<.*?>/g, '')); 10 | } 11 | phantom.exit(); 12 | } 13 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/useragent.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | phantom.state = 'checking' 3 | phantom.userAgent = 'SpecialAgent' 4 | phantom.open 'http://www.httpuseragent.org' 5 | else 6 | console.log document.getElementById('myagent').innerText 7 | phantom.exit() 8 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/useragent.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | phantom.state = 'checking'; 3 | phantom.userAgent = 'SpecialAgent'; 4 | phantom.open('http://www.httpuseragent.org'); 5 | } else { 6 | console.log(document.getElementById('myagent').innerText); 7 | phantom.exit(); 8 | } 9 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/version.coffee: -------------------------------------------------------------------------------- 1 | console.log 'using PhantomJS version ' + 2 | phantom.version.major + '.' + 3 | phantom.version.minor + '.' + 4 | phantom.version.patch 5 | phantom.exit() 6 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/version.js: -------------------------------------------------------------------------------- 1 | console.log('using PhantomJS version ' + 2 | phantom.version.major + '.' + 3 | phantom.version.minor + '.' + 4 | phantom.version.patch); 5 | phantom.exit(); 6 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/waitfor.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Wait until the test condition is true or a timeout occurs. Useful for waiting 3 | on a server response or for a ui change (fadeIn, etc.) to occur. 4 | 5 | @param testFx javascript condition that evaluates to a boolean, 6 | it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 7 | as a callback function. 8 | @param message a message describing e.g. the ui change 9 | @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 10 | ### 11 | waitFor = (testFx, message, maxtimeOutMillis = 3000) -> 12 | start = new Date().getTime() 13 | condition = false 14 | while (new Date().getTime() - start) < maxtimeOutMillis 15 | phantom.sleep(250) 16 | if typeof(testFx) is "string" 17 | condition = eval testFx 18 | else 19 | condition = testFx() 20 | if condition 21 | break 22 | if not condition 23 | console.log "Timeout: " + message 24 | phantom.exit 1 25 | else 26 | console.log message 27 | console.log "+++ waitUntil finished in " + (new Date().getTime() - start) + " millis." 28 | 29 | # example use: 30 | if not phantom.state 31 | # load a twitter page 32 | phantom.state = "loaded" 33 | phantom.open "http://twitter.com/#!/senchainc" 34 | else 35 | # click the "sign in" link 36 | $(".signin-link").click() 37 | 38 | # wait for the sign in dialog to pop up 39 | waitFor (-> $("#signin-dropdown").is ":visible"), "The sign-in dialog should be visible" 40 | phantom.exit() 41 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/waitfor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 3 | * on a server response or for a ui change (fadeIn, etc.) to occur. 4 | * 5 | * @param testFx javascript condition that evaluates to a boolean, 6 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 7 | * as a callback function. 8 | * @param message a message describing e.g. the ui change 9 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 10 | */ 11 | function waitFor(testFx, message, timeOutMillis) { 12 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000; 13 | var start = new Date().getTime(); 14 | var condition = false; 15 | while(new Date().getTime() - start < maxtimeOutMillis) { 16 | phantom.sleep(250); 17 | condition = (typeof(testFx) == "string" ? eval(testFx) : testFx()); 18 | if(condition) break; 19 | } 20 | if(!condition) { 21 | console.log("Timeout: " + message); 22 | phantom.exit(1) 23 | } else { 24 | console.log(message); 25 | console.log("+++ waitUntil finished in " + (new Date().getTime() - start) + " millis."); 26 | } 27 | } 28 | 29 | // example use: 30 | if(!phantom.state) { 31 | // load a twitter page 32 | phantom.state = "loaded"; 33 | phantom.open("http://twitter.com/#!/senchainc"); 34 | } else { 35 | // click the "sign in" link 36 | $(".signin-link").click(); 37 | 38 | // wait for the sign in dialog to pop up 39 | waitFor(function() { 40 | return $("#signin-dropdown").is(":visible"); 41 | }, "The sign-in dialog should be visible"); 42 | phantom.exit(); 43 | } 44 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/weather.coffee: -------------------------------------------------------------------------------- 1 | if phantom.state.length is 0 2 | city = 'Mountain View' 3 | if phantom.args.length > 0 4 | city = phantom.args.join ' ' 5 | phantom.state = city 6 | console.log "Loading #{ city }" 7 | phantom.open encodeURI "http://www.google.com/ig/api?weather=#{ city }" 8 | else 9 | if phantom.loadStatus is 'fail' 10 | console.log 'Unable to access network' 11 | else 12 | if document.querySelectorAll('problem_cause').length > 0 13 | console.log "No data available for #{ phantom.state }" 14 | else 15 | data = (s, e) -> 16 | e = e or document 17 | el = e.querySelector s 18 | if el then el.attributes.data.value else null 19 | 20 | console.log '' 21 | console.log 'City: ' + data 'weather > forecast_information > city' 22 | console.log 'Current condition ' + data 'weather > current_conditions > condition' 23 | console.log 'Temperature: ' + data('weather > current_conditions > temp_f') + ' F' 24 | console.log data 'weather > current_conditions > humidity' 25 | console.log data 'weather > current_conditions > wind_condition' 26 | console.log '' 27 | 28 | forecasts = document.querySelectorAll 'weather > forecast_conditions' 29 | for f in forecasts 30 | console.log "#{ data 'day_of_week', f }: " + 31 | "#{ data 'low', f }-" + 32 | "#{ data 'high', f } F " + 33 | "#{ data 'condition', f }" 34 | 35 | phantom.exit() 36 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/examples/weather.js: -------------------------------------------------------------------------------- 1 | if (phantom.state.length === 0) { 2 | var city = 'Mountain View'; 3 | if (phantom.args.length > 0) { 4 | city = phantom.args.join(' '); 5 | } 6 | phantom.state = city; 7 | console.log('Loading ' + city); 8 | phantom.open(encodeURI('http://www.google.com/ig/api?weather=' + city)); 9 | } else { 10 | 11 | if (phantom.loadStatus === 'fail') { 12 | console.log('Unable to access network'); 13 | } else { 14 | if (document.querySelectorAll('problem_cause').length > 0) { 15 | console.log('No data available for ' + phantom.state); 16 | } else { 17 | function data (s, e) { 18 | var el; 19 | e = e || document; 20 | el = e.querySelector(s); 21 | return el ? el.attributes.data.value : undefined; 22 | }; 23 | 24 | console.log(''); 25 | console.log('City: ' + data('weather > forecast_information > city')); 26 | console.log('Current condition: ' + data('weather > current_conditions > condition')); 27 | console.log('Temperature: ' + data('weather > current_conditions > temp_f') + ' F'); 28 | console.log(data('weather > current_conditions > humidity')); 29 | console.log(data('weather > current_conditions > wind_condition')); 30 | console.log(''); 31 | 32 | var forecasts = document.querySelectorAll('weather > forecast_conditions'); 33 | for (var i = 0; i < forecasts.length; ++i) { 34 | var f = forecasts[i]; 35 | console.log(data('day_of_week', f) + ': ' + 36 | data('low', f) + '-' + data('high', f) + ' F ' + 37 | data('condition', f)); 38 | } 39 | } 40 | } 41 | phantom.exit(); 42 | } 43 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/phantomjs.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | SUBDIRS += src/phantomjs.pro 4 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/INSTALL: -------------------------------------------------------------------------------- 1 | DEPENDENCIES 2 | ------------ 3 | * Python >= 2.6 4 | * PyQt4 >= 4.8.0 5 | * Qt >= 4.7.0 6 | 7 | -> Windows 8 | ------- 9 | You can download the required programs here. 10 | 11 | Python - http://www.python.org/download/ 12 | Qt4 - PyQt4 comes packaged with the Qt runtime library(s) 13 | PyQt4 - http://www.riverbankcomputing.co.uk/software/pyqt/download 14 | 15 | -> Ubuntu 16 | ------ 17 | Open a terminal window, and enter the following command: 18 | "sudo apt-get -y install python-qt4" 19 | 20 | All the required packages should be automatically pulled in and installed. 21 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/csconverter.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This file is part of the PyPhantomJS project. 3 | 4 | Copyright (C) 2011 James Roe 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | from PyQt4.QtCore import QObject, QFile 21 | from PyQt4.QtWebKit import QWebPage 22 | 23 | class CSConverter(QObject): 24 | def __init__(self, parent=None): 25 | QObject.__init__(self, parent) 26 | self.m_webPage = QWebPage(self) 27 | 28 | converter = QFile(':/resources/coffee-script.js') 29 | converter.open(QFile.ReadOnly) 30 | 31 | script = str(converter.readAll()) 32 | converter.close() 33 | self.m_webPage.mainFrame().evaluateJavaScript(script) 34 | self.m_webPage.mainFrame().addToJavaScriptWindowObject('converter', self) 35 | 36 | def convert(self, script): 37 | self.setProperty('source', script) 38 | result = self.m_webPage.mainFrame().evaluateJavaScript('this.CoffeeScript.compile(converter.source)') 39 | if len(result): 40 | return result 41 | return '' 42 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/plugins/saveToFile/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/plugins/saveToFile/saveToFile.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This file is part of the PyPhantomJS project. 3 | 4 | Copyright (C) 2011 James Roe 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | import codecs 21 | 22 | from plugincontroller import add_action 23 | 24 | from PyQt4.QtCore import qWarning, pyqtSlot 25 | 26 | @pyqtSlot(str, str, result=bool) 27 | def saveToFile(self, text, fileName): 28 | fileName = self.m_scriptDir + fileName 29 | try: 30 | f = codecs.open(fileName, 'w+', 'utf-8') 31 | except IOError: 32 | qWarning('phantom.saveToFile - Could not open file: \'%s\'' % fileName) 33 | return False 34 | 35 | f.write(text) 36 | f.close() 37 | 38 | return True 39 | 40 | @add_action('Phantom') 41 | def run(_locals): 42 | _locals.saveToFile = saveToFile 43 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | resources/pyphantomjs-icon.png 4 | resources/coffee-script.js 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/resources/pyphantomjs-icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/phantomjs/python/resources/pyphantomjs-icon.ico -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/resources/pyphantomjs-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/phantomjs/python/resources/pyphantomjs-icon.png -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/tools/build_resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # This script will convert each qrc into a 5 | # Python resource file(s) which can be used 6 | # 7 | # NOTE: This script MUST be called from the same 8 | # directory containing the qrc's! 9 | # 10 | 11 | # convert each filename.qrc to respective filename.py 12 | for f in *.qrc; do 13 | pyrcc4 -compress 2 -o ${f%.*}.py $f 14 | done 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/tools/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | This file is part of the PyPhantomJS project. 4 | 5 | Copyright (C) 2011 James Roe 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ''' 20 | 21 | import sys 22 | # hack to import parent module(s) 23 | sys.path = sys.path + ['..'] 24 | 25 | from utils import version 26 | 27 | try: 28 | from cx_Freeze import setup, Executable 29 | except ImportError: 30 | sys.exit('cx_Freeze must be installed to use this script') 31 | 32 | if sys.platform.startswith('win'): 33 | try: 34 | from win32verstamp import stamp 35 | except ImportError: 36 | from time import sleep 37 | print '*** WARNING ***' 38 | print 'the script will be unable to create the version resource' 39 | print 'install pywin32 extensions if you want the file stamped' 40 | sleep(2) 41 | 42 | exe = Executable( 43 | script = '../pyphantomjs.py', 44 | icon = '../resources/pyphantomjs-icon.ico' 45 | ) 46 | 47 | setup( 48 | name = 'PyPhantomJS', 49 | version = version, 50 | description = 'Minimalistic, headless, WebKit-based, JavaScript-driven tool', 51 | executables = [exe] 52 | ) 53 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/python/webpage.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This file is part of the PyPhantomJS project. 3 | 4 | Copyright (C) 2011 James Roe 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | ''' 19 | 20 | from PyQt4.QtCore import QUrl, QEventLoop, qDebug 21 | from PyQt4.QtGui import QApplication 22 | from PyQt4.QtWebKit import QWebPage 23 | 24 | from plugincontroller import Bunch, do_action 25 | 26 | class WebPage(QWebPage): 27 | def __init__(self, parent=None): 28 | QWebPage.__init__(self, parent) 29 | 30 | self.parent = parent 31 | self.m_nextFileTag = '' 32 | self.m_userAgent = QWebPage.userAgentForUrl(self, QUrl()) 33 | 34 | if self.parent.m_verbose: 35 | self.currentFrame().urlChanged.connect(self.handleFrameUrlChanged) 36 | self.linkClicked.connect(self.handleLinkClicked) 37 | 38 | do_action('WebPageInit', Bunch(locals())) 39 | 40 | def handleFrameUrlChanged(self, url): 41 | qDebug('URL Changed: %s' % url.toString()) 42 | 43 | def handleLinkClicked(self, url): 44 | qDebug('URL Clicked: %s' % url.toString()) 45 | 46 | def javaScriptAlert(self, webframe, msg): 47 | print 'JavaScript alert: %s' % msg 48 | 49 | def javaScriptConsoleMessage(self, message, lineNumber, sourceID): 50 | if sourceID: 51 | print '%s:%d %s' % (sourceID, lineNumber, message) 52 | else: 53 | print message 54 | 55 | def shouldInterruptJavaScript(self): 56 | QApplication.processEvents(QEventLoop.AllEvents, 42) 57 | return False 58 | 59 | def userAgentForUrl(self, url): 60 | return self.m_userAgent 61 | 62 | def chooseFile(self, webframe, suggestedFile): 63 | if self.m_nextFileTag in self.parent.m_upload_file: 64 | return self.parent.m_upload_file[self.m_nextFileTag] 65 | return '' 66 | 67 | do_action('WebPage', Bunch(locals())) 68 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/consts.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef CONSTS_H 31 | #define CONSTS_H 32 | 33 | // Current Version: 1.1.0 34 | #define PHANTOMJS_VERSION_MAJOR 1 35 | #define PHANTOMJS_VERSION_MINOR 1 36 | #define PHANTOMJS_VERSION_PATCH 0 37 | #define PHANTOMJS_VERSION_STRING "1.1.0" 38 | 39 | #endif // CONSTS_H 40 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/csconverter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include "csconverter.h" 31 | 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | // public: 39 | CSConverter::CSConverter(QObject *parent) 40 | : QObject(parent) 41 | { 42 | QFile file(":/coffee-script.js"); 43 | if (!file.open(QFile::ReadOnly)) { 44 | qFatal("CoffeeScript compiler is not available!"); 45 | exit(1); 46 | } 47 | QString script = QString::fromUtf8(file.readAll()); 48 | file.close(); 49 | m_webPage.mainFrame()->evaluateJavaScript(script); 50 | m_webPage.mainFrame()->addToJavaScriptWindowObject("converter", this); 51 | } 52 | 53 | QString CSConverter::convert(const QString &script) 54 | { 55 | setProperty("source", script); 56 | QWebFrame *frame = m_webPage.mainFrame(); 57 | QVariant result = frame->evaluateJavaScript("this.CoffeeScript.compile(converter.source)"); 58 | if (result.type() == QVariant::String) 59 | return result.toString(); 60 | return QString(); 61 | } 62 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/csconverter.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef CSCONVERTER_H 31 | #define CSCONVERTER_H 32 | 33 | #include 34 | #include 35 | 36 | class CSConverter: public QObject 37 | { 38 | public: 39 | CSConverter(QObject *parent = 0); 40 | QString convert(const QString &script); 41 | 42 | private: 43 | QWebPage m_webPage; 44 | }; 45 | 46 | #endif // CSCONVERTER_H 47 | 48 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/gif/config.h: -------------------------------------------------------------------------------- 1 | #define UINT32 uint32_t 2 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/gif/gif.pri: -------------------------------------------------------------------------------- 1 | VPATH += $$PWD 2 | INCLUDEPATH += $$PWD 3 | 4 | DEFINES += HAVE_CONFIG_H 5 | DEFINES += HAVE_STDINT_H 6 | DEFINES += HAVE_FCNTL_H 7 | DEFINES += HAVE_UNISTD_H 8 | DEFINES += HAVE_STDARG_H 9 | 10 | SOURCES += gif_err.c 11 | SOURCES += gifalloc.c 12 | SOURCES += egif_lib.c 13 | SOURCES += gif_hash.c 14 | SOURCES += quantize.c 15 | SOURCES += gifwriter.cpp 16 | 17 | HEADERS += gif_hash.h 18 | HEADERS += gif_lib_private.h 19 | HEADERS += gif_lib.h 20 | HEADERS += gifwriter.h 21 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/gif/gif_hash.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Declarations, global to other of the GIF-HASH.C module. * 3 | * * 4 | * Written by Gershon Elber, Jun 1989 * 5 | ******************************************************************************* 6 | * History: * 7 | * 14 Jun 89 - Version 1.0 by Gershon Elber. * 8 | ******************************************************************************/ 9 | 10 | #ifndef _GIF_HASH_H_ 11 | #define _GIF_HASH_H_ 12 | 13 | #ifdef HAVE_CONFIG_H 14 | #include 15 | #endif 16 | 17 | /* Find a thirty-two bit int type */ 18 | #ifdef HAVE_STDINT_H 19 | #include 20 | #endif 21 | #ifdef HAVE_INTTYPES_H 22 | #include 23 | #endif 24 | #ifdef HAVE_SYS_TYPES_H 25 | #include 26 | #endif 27 | #ifdef HAVE_UNISTD_H 28 | #include 29 | #endif 30 | 31 | #ifdef HAVE_BASETSD_H 32 | #include 33 | #endif 34 | 35 | #define HT_SIZE 8192 /* 12bits = 4096 or twice as big! */ 36 | #define HT_KEY_MASK 0x1FFF /* 13bits keys */ 37 | #define HT_KEY_NUM_BITS 13 /* 13bits keys */ 38 | #define HT_MAX_KEY 8191 /* 13bits - 1, maximal code possible */ 39 | #define HT_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ 40 | 41 | /* The 32 bits of the long are divided into two parts for the key & code: */ 42 | /* 1. The code is 12 bits as our compression algorithm is limited to 12bits */ 43 | /* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits. */ 44 | /* The key is the upper 20 bits. The code is the lower 12. */ 45 | #define HT_GET_KEY(l) (l >> 12) 46 | #define HT_GET_CODE(l) (l & 0x0FFF) 47 | #define HT_PUT_KEY(l) (l << 12) 48 | #define HT_PUT_CODE(l) (l & 0x0FFF) 49 | 50 | typedef struct GifHashTableType { 51 | UINT32 HTable[HT_SIZE]; 52 | } GifHashTableType; 53 | 54 | GifHashTableType *_InitHashTable(void); 55 | void _ClearHashTable(GifHashTableType *HashTable); 56 | void _InsertHashTable(GifHashTableType *HashTable, UINT32 Key, int Code); 57 | int _ExistsHashTable(GifHashTableType *HashTable, UINT32 Key); 58 | 59 | #endif /* _GIF_HASH_H_ */ 60 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/gif/gifwriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef GIFWRITER_H 31 | #define GIFWRITER_H 32 | 33 | #include 34 | #include 35 | 36 | bool exportGif(const QImage &image, const QString &fileName); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | Copyright (C) 2010 Ariya Hidayat 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include "consts.h" 32 | #include "utils.h" 33 | #include "phantom.h" 34 | 35 | #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0) 36 | #error Use Qt 4.5 or later version 37 | #endif 38 | 39 | int main(int argc, char** argv) 40 | { 41 | // Registering an alternative Message Handler 42 | qInstallMsgHandler(Utils::messageHandler); 43 | 44 | // Check number of parameters passed 45 | if (argc < 2) { 46 | Utils::showUsage(); 47 | return 1; 48 | } 49 | 50 | QApplication app(argc, argv); 51 | 52 | app.setWindowIcon(QIcon(":/phantomjs-icon.png")); 53 | app.setApplicationName("PhantomJS"); 54 | app.setOrganizationName("Ofi Labs"); 55 | app.setOrganizationDomain("www.ofilabs.com"); 56 | app.setApplicationVersion(PHANTOMJS_VERSION_STRING); 57 | 58 | // Start Phantom 59 | Phantom phantom; 60 | if (phantom.execute()) { 61 | app.exec(); 62 | } 63 | return phantom.returnValue(); 64 | } 65 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/networkaccessmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef NETWORKACCESSMANAGER_H 31 | #define NETWORKACCESSMANAGER_H 32 | 33 | #include 34 | 35 | class QNetworkDiskCache; 36 | 37 | class NetworkAccessManager : public QNetworkAccessManager 38 | { 39 | Q_OBJECT 40 | QNetworkDiskCache* m_networkDiskCache; 41 | public: 42 | NetworkAccessManager(QObject *parent = 0, bool diskCacheEnabled = false, bool ignoreSslErrors = false); 43 | virtual ~NetworkAccessManager(); 44 | 45 | protected: 46 | bool m_ignoreSslErrors; 47 | QNetworkReply *createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0); 48 | 49 | private slots: 50 | void handleFinished(QNetworkReply *reply); 51 | }; 52 | 53 | #endif // NETWORKACCESSMANAGER_H 54 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/phantomjs/src/phantomjs-icon.png -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = phantomjs 3 | QT += network webkit 4 | CONFIG += console 5 | 6 | # Comment to enable Debug Messages 7 | DEFINES += QT_NO_DEBUG_OUTPUT 8 | 9 | DESTDIR = ../bin 10 | 11 | RESOURCES = phantomjs.qrc 12 | 13 | HEADERS += csconverter.h \ 14 | phantom.h \ 15 | webpage.h \ 16 | consts.h \ 17 | utils.h \ 18 | networkaccessmanager.h 19 | SOURCES += phantom.cpp \ 20 | webpage.cpp \ 21 | main.cpp \ 22 | csconverter.cpp \ 23 | utils.cpp \ 24 | networkaccessmanager.cpp 25 | 26 | include(gif/gif.pri) 27 | 28 | win32: RC_FILE = phantomjs_win.rc 29 | os2: RC_FILE = phantomjs_os2.rc 30 | 31 | # Uncomment to build a Mac OS X Universal Binary (i.e. x86 + ppc) 32 | #mac: CONFIG += x86 ppc 33 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | phantomjs-icon.png 4 | coffee-script.js 5 | usage.txt 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs_os2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/phantomjs/src/phantomjs_os2.ico -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs_os2.rc: -------------------------------------------------------------------------------- 1 | ICON 1 "phantomjs_os2.ico" -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs_win.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoastalResilienceNetwork/GeositeFramework/11cda14251bc290cdfdd890a8f438dc0b025069f/tools/JsTestTools/phantomjs/src/phantomjs_win.ico -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/phantomjs_win.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "phantomjs_win.ico" -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/usage.txt: -------------------------------------------------------------------------------- 1 | 2 | Usage: phantomjs [options] script.[js|coffee] [script argument [script argument ...]] 3 | 4 | Options: 5 | --load-images=[yes|no] Load all inlined images (default is 'yes'). 6 | --load-plugins=[yes|no] Load all plugins (i.e. 'Flash', 'Silverlight', ...) (default is 'no'). 7 | --proxy=address:port Set the network proxy. 8 | --upload-file fileId=/file/path Upload a file by creating a '' 9 | and calling phantom.setFormInputFile(document.getElementById('foo'), 'fileId'). 10 | --disk-cache=[yes|no] Enable disk cache (at desktop services cache storage location, default is 'no'). 11 | --ignore-ssl-errors=[yes|no] Ignore SSL errors (i.e. expired or self-signed certificate errors). 12 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef UTILS_H 31 | #define UTILS_H 32 | 33 | #include 34 | 35 | /** 36 | * Aggregate common utility functions. 37 | * Functions are static methods. 38 | * It's important to notice that, at the moment, this class can't be instantiated by design. 39 | */ 40 | class Utils 41 | { 42 | public: 43 | static void showUsage(); 44 | static void messageHandler(QtMsgType type, const char *msg); 45 | 46 | private: 47 | Utils(); //< This class shouldn't be instantiated 48 | }; 49 | 50 | #endif // UTILS_H 51 | -------------------------------------------------------------------------------- /tools/JsTestTools/phantomjs/src/webpage.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the PhantomJS project from Ofi Labs. 3 | 4 | Copyright (C) 2011 Ariya Hidayat 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef WEBPAGE_H 31 | #define WEBPAGE_H 32 | 33 | #include 34 | 35 | class WebPage: public QWebPage 36 | { 37 | Q_OBJECT 38 | public: 39 | WebPage(QObject *parent = 0); 40 | 41 | public slots: 42 | bool shouldInterruptJavaScript(); 43 | 44 | private slots: 45 | void handleFrameUrlChanged(const QUrl &url); 46 | void handleLinkClicked(const QUrl &url); 47 | 48 | protected: 49 | void javaScriptAlert(QWebFrame *originatingFrame, const QString &msg); 50 | void javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID); 51 | QString userAgentForUrl(const QUrl &url) const; 52 | QString chooseFile(QWebFrame * parentFrame, const QString & suggestedFile); 53 | 54 | private: 55 | QString m_userAgent; 56 | QMap m_allowedFiles; 57 | QString m_nextFileTag; 58 | friend class Phantom; 59 | }; 60 | 61 | #endif // WEBPAGE_H 62 | -------------------------------------------------------------------------------- /tools/JsTestTools/runJstd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ORIGINAL_PATH="$(pwd)" 3 | cd "$(dirname $0)" 4 | # Absolute Path to the bin Dir 5 | BIN_PATH="$(pwd)" 6 | 7 | cd "${BIN_PATH}" 8 | 9 | /usr/bin/env python runJstd.py .. "$1" 10 | cd "${ORIGINAL_PATH}" 11 | -------------------------------------------------------------------------------- /tools/JsTestTools/runJstd.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET SCRIPTPATH=%~p0 4 | SET ABSSCRIPTPATH=%~dp0 5 | SET CWD=%CD% 6 | 7 | cd %ABSSCRIPTPATH% 8 | 9 | python runJstd.py .. %1 10 | if %errorlevel% neq 0 ( 11 | cd %CWD% 12 | exit /b %errorlevel% 13 | ) 14 | cd %CWD% 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/runJstd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script searches for JsTestDriver config files and launches them using 4 | # with the --tests "all" option 5 | import os 6 | import sys 7 | import shutil 8 | import time 9 | from subprocess import call 10 | 11 | if len(sys.argv) > 1: 12 | root_dir = sys.argv[1] 13 | else: 14 | root_dir = ".." # The default assumes that this script is in a subdirectory 15 | # of the project root 16 | 17 | if len(sys.argv) > 2: 18 | browsers = sys.argv[2] 19 | else: 20 | browsers = "NO_BROWSERS_SPECIFIED" 21 | 22 | detect = "server:" 23 | script_path = os.path.dirname(os.path.abspath(__file__)) 24 | output_path = os.path.join(script_path, "output") 25 | 26 | # Clean the ouput from a previous run 27 | if os.path.exists(output_path): 28 | shutil.rmtree(output_path) 29 | os.mkdir(output_path) 30 | 31 | matched_files = [] 32 | print "Searching for JsTestDriver conf files..." 33 | for dname, dirs, files in os.walk(root_dir): 34 | if not '.git' in dname: 35 | for fname in files: 36 | if fname.endswith(".conf"): 37 | fpath = os.path.join(dname, fname) 38 | for line in open(fpath): 39 | if detect in line: 40 | matched_files.append(fpath) 41 | break 42 | 43 | if len(matched_files) > 0: 44 | for matched_file in matched_files: 45 | print "Running configuration " + matched_file 46 | return_code = call(['java', '-jar', os.path.join(script_path, 'jstestdriver', 'JsTestDriver-1.3.1.jar'), 47 | '--reset', '--port', '9876', '--browser', browsers, '--tests', 'all', '--config', matched_file, '--testOutput', output_path]) 48 | # running JSTD jobs too close together sometimes causes a failure because 49 | # the browser is not yet available for a new job. 50 | time.sleep(0.5) 51 | else: 52 | print "No JSTestDriver conf files found in " + root_dir 53 | -------------------------------------------------------------------------------- /tools/JsTestTools/runPhantom: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ORIGINAL_PATH="$(pwd)" 3 | cd "$(dirname $0)" 4 | # Absolute Path to the bin Dir 5 | BIN_PATH="$(pwd)" 6 | 7 | cd "${BIN_PATH}" 8 | 9 | /usr/bin/env python runPhantom.py .. 10 | cd "${ORIGINAL_PATH}" 11 | -------------------------------------------------------------------------------- /tools/JsTestTools/runPhantom.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | SET SCRIPTPATH=%~p0 4 | SET ABSSCRIPTPATH=%~dp0 5 | SET CWD=%CD% 6 | 7 | cd %ABSSCRIPTPATH% 8 | 9 | python runPhantom.py .. 10 | if %errorlevel% neq 0 ( 11 | cd %CWD% 12 | exit /b %errorlevel% 13 | ) 14 | cd %CWD% 15 | -------------------------------------------------------------------------------- /tools/JsTestTools/runPhantom.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script searches for HTML files that run Jasmine unit test suites and 4 | # opens them using PyPhantomJS 5 | import os 6 | import sys 7 | import shutil 8 | from subprocess import call 9 | 10 | if len(sys.argv) > 1: 11 | root_dir = sys.argv[1] 12 | else: 13 | root_dir = ".." # The default assumes that this script is in a subdirectory 14 | # of the project root 15 | 16 | detect = "jasmine.getEnv().execute()" 17 | script_path = os.path.dirname(os.path.abspath(__file__)) 18 | output_path = os.path.join(script_path, "output") 19 | 20 | # Clean the ouput from a previous run 21 | if os.path.exists(output_path): 22 | shutil.rmtree(output_path) 23 | os.mkdir(output_path) 24 | 25 | matched_files = [] 26 | print "Searching for html files that launch Jasmine test suites..." 27 | for dname, dirs, files in os.walk(root_dir): 28 | if not '.git' in dname: 29 | for fname in files: 30 | if fname.endswith(".html"): 31 | if fname.lower() != "specrunnertemplate.html": 32 | fpath = os.path.join(dname, fname) 33 | for line in open(fpath): 34 | if detect in line: 35 | matched_files.append(fpath) 36 | break 37 | 38 | # The XML file output seems to only work when pyphantomjs.py is launched 39 | # from the directory in which it is saved. 40 | os.chdir(os.path.join(script_path, "phantomjs", "python")) 41 | 42 | for matched_file in matched_files: 43 | print "Running tests in " + matched_file 44 | return_code = call(['python', 'pyphantomjs.py', os.path.join('..', '..', 'phantomjs-testrunner.js'), os.path.join('..', '..', matched_file)]) 45 | --------------------------------------------------------------------------------