├── .bowerrc ├── .dockerignore ├── .gitignore ├── .gitmodules ├── .jshintrc ├── .travis.yml ├── AUTHORS ├── COPYING ├── CREDITS ├── ChangeLog ├── Dockerfile ├── Gruntfile.js ├── LICENSE ├── Makefile.am ├── NEWS ├── README.Docker.md ├── README.md ├── app ├── config.json ├── data │ ├── cert.ttl │ ├── dcterms.ttl │ ├── foaf.ttl │ ├── gr.ttl │ ├── rdf.ttl │ ├── rdfs.ttl │ ├── schema.ttl │ ├── sioc.ttl │ ├── skos-ext.ttl │ ├── skos.ttl │ ├── space.ttl │ ├── vcard.ttl │ └── void.ttl ├── images │ ├── clear.png │ ├── favicons │ │ ├── android-chrome-144x144.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-36x36.png │ │ ├── android-chrome-48x48.png │ │ ├── android-chrome-72x72.png │ │ ├── android-chrome-96x96.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-precomposed.png │ │ ├── apple-touch-icon.png │ │ ├── browserconfig.xml │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── manifest.json │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── mstile-70x70.png │ │ └── safari-pinned-tab.svg │ ├── loading.gif │ ├── oplogo_std_100x40.png │ └── osdelogo_std_32.png ├── index.html ├── scripts │ ├── app.js │ └── controllers │ │ ├── browser.js │ │ ├── editor.js │ │ └── welcome.js ├── styles │ └── app.css ├── tmpl │ └── authinfodlg.html └── views │ ├── browser.html │ ├── editor.html │ └── welcome.html ├── autogen.sh ├── bower.json ├── build.bat ├── build.sh ├── configure.ac ├── css ├── backbone-forms-bootstrap3.css ├── bootstrap-datetimepicker.min.css ├── bootstrap-editable.css ├── bootstrap-fixes.css ├── bootstrap-table.min.css ├── bootstrap-theme.css ├── bootstrap-theme.css.map ├── bootstrap-theme.min.css ├── bootstrap-toggle.min.css ├── jquery.rdfnodeinput.css ├── rdfe.css └── selectize.bootstrap3.css ├── e2e-tests ├── protractor.conf.js └── scenarios.js ├── gen_version.sh ├── karma.conf.js ├── package.json ├── rdf-editor-sticker.xml ├── src ├── core │ ├── config.js │ ├── dav.js │ ├── document.js │ ├── io.js │ ├── ontology.js │ ├── rdf_store_ext.js │ ├── rdfnode.js │ ├── utils.js │ └── validate.js ├── deps-demo │ ├── bootbox.min.js │ ├── bootstrap-notify.min.js │ ├── dummy.js │ ├── jquery-deparam.min.js │ ├── jquery.cookie.js │ ├── jquery.spin.js │ ├── jstorage.js │ └── spin.js ├── deps-orig │ ├── backbone-forms.js │ ├── backbone-min.js │ ├── backbone-min.map │ ├── bootstrap-datetimepicker.min.js │ ├── bootstrap-editable.js │ ├── bootstrap-table-editable.js │ ├── bootstrap-toggle.min.js │ ├── bootstrap.js │ ├── jquery.md5.js │ ├── n3-browser.min.js │ ├── selectize.js │ ├── underscore-min.js │ └── underscore-min.map ├── deps │ ├── backbone-forms-bootstrap3.js │ ├── backbone-forms-list.js │ ├── bootstrap-table.js │ ├── rdf_store.js │ └── rdfxml_parser.js └── ui │ ├── backbone-forms-nestedrdf.js │ ├── backbone-forms-rdfnode.js │ ├── editable-propertybox.js │ ├── editable-rdfnode.js │ ├── editor.js │ ├── entityeditor.js │ ├── entitymodel.js │ ├── entityview.js │ ├── jquery.ontobox.js │ ├── jquery.propertybox.js │ ├── jquery.rdfnodeinput.js │ ├── objecteditor.js │ ├── objectview.js │ ├── ontologyview.js │ ├── predicateeditor.js │ ├── predicateview.js │ ├── subjecteditor.js │ ├── subjectview.js │ └── tripleview.js └── vad_version /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .tmp/ 3 | app/bower_components/ 4 | autom4te.cache/ 5 | node_modules/ 6 | *.vad 7 | *.tar.gz 8 | *.zip 9 | aclocal.m4 10 | config.log 11 | config.nice 12 | config.status 13 | configure 14 | install-sh 15 | Makefile 16 | Makefile.in 17 | missing 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | INSTALL 2 | .tmp/ 3 | Makefile 4 | Makefile.in 5 | aclocal.m4 6 | app/bower_components/ 7 | autom4te.cache/ 8 | config.log 9 | config.nice 10 | config.status 11 | configure 12 | dist/ 13 | install-sh 14 | missing 15 | node_modules/ 16 | rdf_editor_dav.vad 17 | rdf_editor_pkg.tar.gz 18 | rdf_editor_pkg.zip 19 | gen_version 20 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vadpacker"] 2 | path = vadpacker 3 | url = https://github.com/openlink/vadpacker 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globalstrict": true, 3 | "globals": { 4 | "angular": false, 5 | "describe": false, 6 | "it": false, 7 | "expect": false, 8 | "beforeEach": false, 9 | "afterEach": false, 10 | "module": false, 11 | "inject": false 12 | } 13 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | before_script: 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start 8 | - npm start > /dev/null & 9 | - npm run update-webdriver 10 | - sleep 1 # give server time to start 11 | 12 | script: 13 | - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox 14 | - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox 15 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # 2 | # List of Authors/Contributors 3 | # 4 | # This file is part of the OpenLink RDF Editor 5 | # 6 | # Copyright (C) 2014-2025 OpenLink Software 7 | # 8 | # This project is free software; you can redistribute it and/or modify it 9 | # under the terms of the GNU General Public License as published by the 10 | # Free Software Foundation; only version 2 of the License, dated June 1991. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License along 18 | # with this program; if not, write to the Free Software Foundation, Inc., 19 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | # 22 | 23 | Current Maintainer 24 | ------------------ 25 | Patrick van Kleef opensource{at}openlinksw.com 26 | 27 | 28 | Author 29 | ------- 30 | Sebastian Trueg trueg{at}openlinksw.com 31 | 32 | 33 | Contributors 34 | ------------ 35 | Aziz Baktiev abaktief{at}openlinksw.com 36 | Dimitar Dimitrov ddimitrov{at}openlinksw.com 37 | Kingsley Idehen kidehen{at}openlinksw.com 38 | Patrick van Kleef pkleef{at}openlinksw.com 39 | Tim Haynes thaynes{at}openlinksw.com 40 | 41 | 42 | This list may not complete. If you have contributed to this project and want to appear on this list, 43 | please email the current maintainer. 44 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | # 2 | # CREDITS 3 | # 4 | # This file is part of the OpenLink RDF Editor 5 | # 6 | # Copyright (C) 2014-2025 OpenLink Software 7 | # 8 | # This project is free software; you can redistribute it and/or modify it 9 | # under the terms of the GNU General Public License as published by the 10 | # Free Software Foundation; only version 2 of the License, dated June 1991. 11 | # 12 | # This program is distributed in the hope that it will be useful, but 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License along 18 | # with this program; if not, write to the Free Software Foundation, Inc., 19 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | # 21 | # 22 | 23 | The OpenLink Software RDF Editor project wishes to acknowledge incorporation of code from the 24 | following projects: 25 | 26 | * angular 27 | Project : https://angularjs.org/ 28 | License : MIT license 29 | Description : 30 | HTML enhanced for web apps! 31 | 32 | 33 | * angular-spinner 34 | Project : https://github.com/urish/angular-spinner 35 | License : MIT license 36 | Description : 37 | Angular directive to show an animated spinner (using spin.js) 38 | 39 | 40 | * backbone.js 41 | Project : http://backbonejs.org/ 42 | License : MIT license 43 | Description : 44 | Backbone.js gives structure to web applications by providing models with key-value binding 45 | and custom events, collections with a rich API of enumerable functions, views with 46 | declarative event handling, and connects it all to your existing API over a RESTful JSON 47 | interface. 48 | 49 | 50 | * backbone-forms.js 51 | Project : https://github.com/powmedia/backbone-forms 52 | License : https://github.com/powmedia/backbone-forms/blob/master/LICENSE, looks like MIT license 53 | Description : 54 | Form framework for BackboneJS with nested forms, editable lists and validation 55 | 56 | 57 | * bootbox.js 58 | Project : http://bootboxjs.com/ 59 | License : MIT license 60 | Description : 61 | Bootbox.js is a small JavaScript library which allows you to create programmatic dialog 62 | boxes using Bootstrap modals, without having to worry about creating, managing or removing 63 | any of the required DOM elements or JS event handlers. 64 | 65 | 66 | * bootstrap.js 67 | Project : http://getbootstrap.com/ 68 | License : MIT license 69 | Description : 70 | Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile 71 | first projects on the web. 72 | 73 | 74 | * bootstrap-datetimepicker.js 75 | Project : https://github.com/smalot/bootstrap-datetimepicker 76 | License : Apache License V2.0 77 | Description : 78 | Date and Time picker widget based on twitter bootstrap. 79 | 80 | 81 | * bootstrap-editable.js 82 | Project : http://vitalets.github.io/x-editable/ 83 | License : MIT license 84 | Description : 85 | This library allows you to create editable elements on your page. It can be used with any 86 | engine (bootstrap, jquery-ui, jquery only) and includes both popup and inline modes. 87 | 88 | 89 | * bootstrap-growl.js 90 | Project : https://github.com/mouse0270/bootstrap-growl 91 | License : MIT license 92 | Description : 93 | Turns standard Bootstrap alerts into "Growl-like" notifications. 94 | 95 | 96 | * bootstrap-table.js 97 | Project : http://bootstrap-table.wenzhixin.net.cn/ 98 | License : MIT license 99 | Description : 100 | An extended Bootstrap table with radio, checkbox, sort, pagination, and other added features. 101 | 102 | 103 | * bootstrap-table-editable.js 104 | Project : http://bootstrap-table.wenzhixin.net.cn/extensions/ 105 | License : MIT license 106 | Description : 107 | The extensions of bootstrap table. 108 | 109 | 110 | * bootstrap-toggle.js 111 | Project : http://www.bootstraptoggle.com/ 112 | License : MIT license 113 | Description : 114 | Bootstrap Toggle is a highly flexible Bootstrap plugin that converts checkboxes into toggles. 115 | 116 | 117 | * jQuery 118 | Project : https://jquery.com/ 119 | License : https://github.com/jquery/jquery/blob/master/LICENSE.txt, looks like MIT license 120 | Description : 121 | jQuery is a fast, small, and feature-rich JavaScript library. 122 | It makes things like HTML document traversal and manipulation, 123 | event handling, animation, and Ajax much simpler with an 124 | easy-to-use API that works across a multitude of browsers. 125 | 126 | 127 | * jquery.cookie.js 128 | Project : https://github.com/carhartl/jquery-cookie 129 | License : MIT license 130 | Description : 131 | A simple, lightweight jQuery plugin for reading, writing and deleting cookies. 132 | 133 | 134 | * jquery-depparam.js 135 | Project : https://github.com/chrissrogers/jquery-deparam 136 | License : based on http://benalman.com/projects/jquery-bbq-plugin/which is dual licensed under the MIT and GPL licenses 137 | Description : 138 | An extraction of the deparam method from Ben Alman's jQuery BBQ. 139 | 140 | 141 | * jquery.md5.js 142 | Project : https://github.com/blueimp/jQuery-MD5 143 | License : MIT license 144 | Description : 145 | JavaScript MD5 implementation. 146 | 147 | 148 | * N3.js 149 | Project : https://github.com/RubenVerborgh/N3.js 150 | License : MIT license 151 | Description : 152 | Lightning fast, asynchronous, streaming RDF for JavaScript. 153 | 154 | 155 | * rdf_store.js 156 | Project : https://github.com/antoniogarrote/rdfstore-js 157 | License : MIT license 158 | Description : 159 | JS RDF store with SPARQL support. 160 | 161 | 162 | * selectize.js 163 | Project : http://brianreavis.github.io/selectize.js/ 164 | License : Apache License V2.0 165 | Description : 166 | Selectize is the hybrid of a textbox and 11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /app/views/browser.html: -------------------------------------------------------------------------------- 1 |

2 |
3 |

Storage Locations

4 | 58 |
59 | 60 |
61 |

62 | {{currentFolder.path}} on {{currentFolder.host}} 63 |
64 | 67 |
68 | 69 |
70 |
71 |

72 | 73 | 143 |
144 | -------------------------------------------------------------------------------- /app/views/welcome.html: -------------------------------------------------------------------------------- 1 |
2 | 13 | 14 |
15 |
16 |

17 | This Editor enables editing of Structured Data documents (using abstract RDF Language) stored 18 | in a variety of HTTP accessible documents (Turtle or JSON-LD content formats). 19 | Actual document access requires the target document is served from a system that supports at 20 | least one of the following HTTP based open standards: Linked Data Platform (LDP), WebDAV, SPARQL 1.1 Update, or the SPARQL Graph Protocol. 21 | Get started by creating a brand new document or opening up an existing document. 22 |

23 | Examples: 24 |
25 | [1] About DBpedia 26 |
27 | [2] About OpenLink Software 28 |

29 |
30 | 31 | Create New Document 32 | Open Document 33 |
34 |
35 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # autogen.sh 4 | # 5 | # Bootstrap the project so we do not need to maintain the 6 | # files generated by autoconf, automake and libtool 7 | # 8 | # This file is part of the OpenLink RDF Editor 9 | # 10 | # Copyright (C) 2014-2025 OpenLink Software 11 | # 12 | # This project is free software; you can redistribute it and/or modify it 13 | # under the terms of the GNU General Public License as published by the 14 | # Free Software Foundation; only version 2 of the License, dated June 1991. 15 | # 16 | # This program is distributed in the hope that it will be useful, but 17 | # WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | # General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License along 22 | # with this program; if not, write to the Free Software Foundation, Inc., 23 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 | # 25 | # 26 | 27 | echo "Initializing git submodules" 28 | 29 | git submodule update --init 30 | 31 | echo "Generating configure files... may take a while." 32 | 33 | autoreconf --install --force && \ 34 | echo "Preparing was successful if there was no error messages above." && \ 35 | echo "Now type:" && \ 36 | echo " ./configure && make" && \ 37 | echo "Run './configure --help' for more information" 38 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rdf-editor", 3 | "description": "OpenLink Structured Data Editor", 4 | "version": "0.18.0", 5 | "homepage": "http://www.openlinksw.com", 6 | "license": "GPL-2.0", 7 | "private": true, 8 | "dependencies": { 9 | "bootstrap": "3.4.0", 10 | "angular": "1.7.x", 11 | "angular-route": "1.7.x", 12 | "angular-loader": "1.7.x", 13 | "angular-mocks": "1.7.x", 14 | "angular-bootstrap": "2.x", 15 | "html5-boilerplate": "~6.1.x", 16 | "spin.js": "~2.0.0", 17 | "angular-spinner": "~0.8.x" 18 | }, 19 | "resolutions": { 20 | "angular": "1.5.x" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | REM 2 | REM This file is part of the OpenLink RDF Editor 3 | REM 4 | REM Copyright (C) 2015-2025 OpenLink Software 5 | REM 6 | REM This project is free software; you can redistribute it and/or modify it 7 | REM under the terms of the GNU General Public License as published by the 8 | REM Free Software Foundation; only version 2 of the License, dated June 1991. 9 | REM 10 | REM This program is distributed in the hope that it will be useful, but 11 | REM WITHOUT ANY WARRANTY; without even the implied warranty of 12 | REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | REM General Public License for more details. 14 | REM 15 | REM You should have received a copy of the GNU General Public License along 16 | REM with this program; if not, write to the Free Software Foundation, Inc., 17 | REM 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | REM 19 | REM 20 | 21 | npm install 22 | 23 | bower install 24 | 25 | grunt build 26 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This file is part of the OpenLink RDF Editor 4 | # 5 | # Copyright (C) 2015-2025 OpenLink Software 6 | # 7 | # This project is free software; you can redistribute it and/or modify it 8 | # under the terms of the GNU General Public License as published by the 9 | # Free Software Foundation; only version 2 of the License, dated June 1991. 10 | # 11 | # This program is distributed in the hope that it will be useful, but 12 | # WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License along 17 | # with this program; if not, write to the Free Software Foundation, Inc., 18 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | # 20 | # 21 | 22 | LC_ALL=C 23 | export LC_ALL 24 | 25 | npm install 26 | 27 | bower install 28 | 29 | grunt build 30 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | define([RDF_EDITOR_VERSION], [esyscmd([./gen_version.sh | sed -e 's/_git.*//' | tr -d '\n'])]) 2 | 3 | AC_INIT([rdf-editor], [RDF_EDITOR_VERSION], [opensource@openlinksw.com]) 4 | AM_INIT_AUTOMAKE([foreign]) 5 | AM_MAINTAINER_MODE 6 | 7 | # -------------------------------------------------------------- 8 | # Save configuration for later reuse 9 | # -------------------------------------------------------------- 10 | echo creating config.nice 11 | rm -f config.nice 12 | cat >config.nice<> config.nice 26 | fi 27 | done 28 | 29 | echo "" >> config.nice 30 | echo ${SHELL} "\"$0\" \\" >> config.nice 31 | 32 | eval "set -- $ac_configure_args" 33 | 34 | for arg 35 | do 36 | echo "\"$arg\" \\" >> config.nice 37 | done 38 | 39 | echo '"$@"' >> config.nice 40 | chmod +x config.nice 41 | 42 | 43 | 44 | # -------------------------------------------------------------- 45 | # Check for python (vadpacker) 46 | # -------------------------------------------------------------- 47 | AM_PATH_PYTHON([2.7.5]) 48 | 49 | 50 | # -------------------------------------------------------------- 51 | # Check for vadpacker as distributed with Virtuoso 52 | # Allow a manual override 53 | # -------------------------------------------------------------- 54 | AC_ARG_WITH( 55 | [vadpacker], 56 | [AS_HELP_STRING( 57 | [--with-vadpacker=DIR], 58 | [Specify the full path to the vadpacker script to use. If not provided configure will search the PATH.])], 59 | [ 60 | case "$withval" in 61 | yes|no) 62 | vadpacker_dir=$srcdir/vadpacker 63 | ;; 64 | *) 65 | vadpacker_dir="$withval" 66 | ;; 67 | esac 68 | ],[vadpacker_dir=$srcdir/vadpacker]) 69 | 70 | abs_vadpacker_dir=`cd "$vadpacker_dir" && pwd` 71 | AC_PATH_PROG([VADPACKER], [vadpacker.py], notfound, ["$abs_vadpacker_dir:$PATH"]) 72 | if test "x$VADPACKER" = "xnotfound"; then 73 | AC_MSG_ERROR([cannot find vadpacker.py. Consider using --with-vadpacker=DIR]) 74 | fi 75 | 76 | 77 | # -------------------------------------------------------------- 78 | # Allow to specify the installation vad dir 79 | # -------------------------------------------------------------- 80 | AC_ARG_WITH( 81 | [vaddir], 82 | [AS_HELP_STRING( 83 | [--with-vaddir=PATH], 84 | [Specify the full path to where the vad packages should be installed. Defaults to DATADIR/virtuoso/vad.])], 85 | [vaddir=${withval}], 86 | [vaddir=$datadir/virtuoso/vad]) 87 | 88 | 89 | # Make all required variables available 90 | AC_SUBST([vaddir]) 91 | 92 | AC_CONFIG_FILES([Makefile]) 93 | 94 | AC_OUTPUT 95 | 96 | echo "" 97 | echo "Configuration results:" 98 | echo "----------------------" 99 | echo "VAD version: $PACKAGE_VERSION" 100 | echo "Python: $PYTHON ($PYTHON_VERSION)" 101 | echo "Vadpacker: $VADPACKER" 102 | echo "" 103 | -------------------------------------------------------------------------------- /css/backbone-forms-bootstrap3.css: -------------------------------------------------------------------------------- 1 | /* Date */ 2 | .bbf-date .bbf-date { 3 | width: 4em 4 | } 5 | 6 | .bbf-date .bbf-month { 7 | width: 9em; 8 | } 9 | 10 | .bbf-date .bbf-year { 11 | width: 5em; 12 | } 13 | 14 | 15 | /* DateTime */ 16 | .bbf-datetime select { 17 | width: 4em; 18 | } 19 | 20 | 21 | /* List */ 22 | .bbf-list .bbf-add { 23 | margin-top: -10px 24 | } 25 | 26 | .bbf-list li { 27 | margin-bottom: 5px 28 | } 29 | 30 | .bbf-list li:last-child { 31 | margin-bottom: 0; 32 | } 33 | 34 | .bbf-list .bbf-del { 35 | margin-left: 4px 36 | } 37 | 38 | 39 | /* List.Modal */ 40 | .bbf-list-modal { 41 | cursor: pointer; 42 | border: 1px solid #ccc; 43 | width: 208px; 44 | border-radius: 3px; 45 | padding: 4px; 46 | color: #555; 47 | } 48 | 49 | .bbf-list ul { 50 | margin-bottom: 0; 51 | } 52 | 53 | .bbf-list { 54 | display: table; 55 | width: 100%; 56 | } 57 | 58 | .bbf-list .bbf-list-contents, .bbf-list-buttons { 59 | display: table-cell; 60 | } 61 | 62 | .bbf-list .bbf-list-buttons { 63 | vertical-align: bottom; 64 | } 65 | -------------------------------------------------------------------------------- /css/bootstrap-fixes.css: -------------------------------------------------------------------------------- 1 | @media (min-width: 768px) { 2 | .navbar-fixed-top .navbar-collapse, 3 | .navbar-static-top .navbar-collapse, 4 | .navbar-fixed-bottom .navbar-collapse { 5 | padding-right: 15px; 6 | padding-left: 15px; 7 | } 8 | } 9 | .form-horizontal .form-group { 10 | margin-right: 0px; 11 | margin-left: 0px; 12 | } 13 | 14 | .input-group .form-control { 15 | z-index: auto; 16 | } 17 | 18 | .input-group-btn { 19 | vertical-align: bottom; 20 | } 21 | .label-as-badge { 22 | border-radius: 1em; 23 | } 24 | -------------------------------------------------------------------------------- /css/bootstrap-table.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * bootstrap-table - An extended Bootstrap table with radio, checkbox, sort, pagination, and other added features. (supports twitter bootstrap v2 and v3). 3 | * 4 | * @version v1.13.3 5 | * @homepage https://bootstrap-table.com 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .bootstrap-table .fixed-table-toolbar:after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-toolbar .bs-bars,.bootstrap-table .fixed-table-toolbar .search,.bootstrap-table .fixed-table-toolbar .columns{position:relative;margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group>.btn{border-radius:0}.bootstrap-table .fixed-table-toolbar .columns .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.bootstrap-table .fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429}.bootstrap-table .fixed-table-toolbar .columns-left{margin-right:5px}.bootstrap-table .fixed-table-toolbar .columns-right{margin-left:5px}.bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu{right:0;left:auto}.bootstrap-table .fixed-table-container{position:relative;clear:both}.bootstrap-table .fixed-table-container.fixed-height{border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border{border-left:1px solid #dee2e6;border-right:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table thead th{border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th{border-bottom:1px solid #32383e}.bootstrap-table .fixed-table-container .fixed-table-header{overflow:hidden}.bootstrap-table .fixed-table-container .fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.bootstrap-table .fixed-table-container .table{width:100%;margin-bottom:0!important}.bootstrap-table .fixed-table-container .table th,.bootstrap-table .fixed-table-container .table td{vertical-align:middle;box-sizing:border-box}.bootstrap-table .fixed-table-container .table thead th{vertical-align:bottom;padding:0;margin:0}.bootstrap-table .fixed-table-container .table thead th:focus{outline:0 solid transparent}.bootstrap-table .fixed-table-container .table thead th.detail{width:30px}.bootstrap-table .fixed-table-container .table thead th .th-inner{padding:.75rem;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap-table .fixed-table-container .table thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.bootstrap-table .fixed-table-container .table thead th .both{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC")}.bootstrap-table .fixed-table-container .table thead th .asc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==")}.bootstrap-table .fixed-table-container .table thead th .desc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ")}.bootstrap-table .fixed-table-container .table tbody tr.selected td{background-color:rgba(0,0,0,0.075)}.bootstrap-table .fixed-table-container .table tbody tr.no-records-found{text-align:center}.bootstrap-table .fixed-table-container .table tbody tr .card-view .title{font-weight:bold;display:inline-block;min-width:30%;text-align:left!important}.bootstrap-table .fixed-table-container .table .bs-checkbox{text-align:center}.bootstrap-table .fixed-table-container .table input[type="radio"],.bootstrap-table .fixed-table-container .table input[type="checkbox"]{margin:0 auto!important}.bootstrap-table .fixed-table-container .table.table-sm .th-inner{padding:.3rem}.bootstrap-table .fixed-table-container .fixed-table-footer{overflow:hidden;border-top:1px solid #dee2e6}.bootstrap-table .fixed-table-container .fixed-table-footer .table{border-bottom:0;border-radius:0;padding:0!important}.bootstrap-table .fixed-table-container .fixed-table-footer .table tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-pagination:after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-pagination>.pagination-detail,.bootstrap-table .fixed-table-pagination>.pagination{margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-pagination>.pagination-detail .pagination-info{line-height:34px;margin-right:5px}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list{display:inline-block}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group{position:relative;display:inline-block;vertical-align:middle}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group .dropdown-menu{margin-bottom:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination{margin:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination a{padding:6px 12px;line-height:1.428571429}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a{color:#c8c8c8}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a:before{content:'\2B05'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a:after{content:'\27A1'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.disabled a{pointer-events:none;cursor:default}.bootstrap-table.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%!important;background:#FFF}div.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden} -------------------------------------------------------------------------------- /css/bootstrap-toggle.min.css: -------------------------------------------------------------------------------- 1 | /*! ======================================================================== 2 | * Bootstrap Toggle: bootstrap-toggle.css v2.2.0 3 | * http://www.bootstraptoggle.com 4 | * ======================================================================== 5 | * Copyright 2014 Min Hur, The New York Times Company 6 | * Licensed under MIT 7 | * ======================================================================== */ 8 | .checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px} 9 | .toggle{position:relative;overflow:hidden} 10 | .toggle input[type=checkbox]{display:none} 11 | .toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none} 12 | .toggle.off .toggle-group{left:-100%} 13 | .toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0} 14 | .toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0} 15 | .toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px} 16 | .toggle.btn{min-width:59px;min-height:34px} 17 | .toggle-on.btn{padding-right:24px} 18 | .toggle-off.btn{padding-left:24px} 19 | .toggle.btn-lg{min-width:79px;min-height:45px} 20 | .toggle-on.btn-lg{padding-right:31px} 21 | .toggle-off.btn-lg{padding-left:31px} 22 | .toggle-handle.btn-lg{width:40px} 23 | .toggle.btn-sm{min-width:50px;min-height:30px} 24 | .toggle-on.btn-sm{padding-right:20px} 25 | .toggle-off.btn-sm{padding-left:20px} 26 | .toggle.btn-xs{min-width:35px;min-height:22px} 27 | .toggle-on.btn-xs{padding-right:12px} 28 | .toggle-off.btn-xs{padding-left:12px} -------------------------------------------------------------------------------- /css/jquery.rdfnodeinput.css: -------------------------------------------------------------------------------- 1 | .rdfNodeEditor > input.has-error { 2 | border-color: #a94442; 3 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 4 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075) 5 | } 6 | 7 | .rdfNodeEditor > input.has-error:focus { 8 | border-color: #843534; 9 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483; 10 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483 11 | } 12 | 13 | .rdfNodeEditor { 14 | display: table; 15 | width: 100%; 16 | } 17 | 18 | .rdfNodeInputContainer { 19 | display: table-cell; 20 | } 21 | .rdfNodeLangContainer { 22 | display: table-cell; 23 | margin-left: 5px; 24 | } 25 | .rdfNodeLangContainer .input-group { 26 | /* width: 100%;*/ 27 | } 28 | .rdfNodeTypeContainer { 29 | display: table-cell; 30 | margin-left: 5px; 31 | } 32 | -------------------------------------------------------------------------------- /css/rdfe.css: -------------------------------------------------------------------------------- 1 | textarea { 2 | min-height: 5em; 3 | resize: vertical; 4 | } 5 | 6 | .rdfe-entity-label { 7 | font-weight: bold; 8 | } 9 | 10 | .rdfe-entity-types { 11 | font-size: 0.7em; 12 | font-style: italic; 13 | } 14 | 15 | .rdfe-small-column { 16 | white-space: nowrap; 17 | padding-right: 1em; 18 | width: 1%; 19 | } 20 | 21 | .rdfe-font-bold { 22 | font-weight: bold; 23 | } 24 | 25 | .rdfe-reference-link { 26 | display: inline-block; 27 | vertical-align: top; 28 | margin-left: 7px; 29 | zoom: 1; 30 | } 31 | 32 | .rdfe-green-link { 33 | color: green; 34 | } 35 | 36 | .fixed-table-toolbar .search { 37 | margin-top: 0px !important; 38 | margin-bottom: 0px !important; 39 | } -------------------------------------------------------------------------------- /e2e-tests/protractor.conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | allScriptsTimeout: 11000, 3 | 4 | specs: [ 5 | '*.js' 6 | ], 7 | 8 | capabilities: { 9 | 'browserName': 'chrome' 10 | }, 11 | 12 | baseUrl: 'http://localhost:8000/app/', 13 | 14 | framework: 'jasmine', 15 | 16 | jasmineNodeOpts: { 17 | defaultTimeoutInterval: 30000 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /e2e-tests/scenarios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* https://github.com/angular/protractor/blob/master/docs/toc.md */ 4 | 5 | describe('my app', function() { 6 | 7 | browser.get('index.html'); 8 | 9 | it('should automatically redirect to /view1 when location hash/fragment is empty', function() { 10 | expect(browser.getLocationAbsUrl()).toMatch("/view1"); 11 | }); 12 | 13 | 14 | describe('view1', function() { 15 | 16 | beforeEach(function() { 17 | browser.get('index.html#/view1'); 18 | }); 19 | 20 | 21 | it('should render view1 when user navigates to /view1', function() { 22 | expect(element.all(by.css('[ng-view] p')).first().getText()). 23 | toMatch(/partial for view 1/); 24 | }); 25 | 26 | }); 27 | 28 | 29 | describe('view2', function() { 30 | 31 | beforeEach(function() { 32 | browser.get('index.html#/view2'); 33 | }); 34 | 35 | 36 | it('should render view2 when user navigates to /view2', function() { 37 | expect(element.all(by.css('[ng-view] p')).first().getText()). 38 | toMatch(/partial for view 2/); 39 | }); 40 | 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /gen_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This file is part of the OpenLink RDF Editor 4 | # 5 | # Copyright (C) 2015-2025 OpenLink Software 6 | # 7 | # Calculate version number for vad package based on the number of 8 | # commits since the last release 9 | # 10 | # This project is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the 12 | # Free Software Foundation; only version 2 of the License, dated June 1991. 13 | # 14 | # This program is distributed in the hope that it will be useful, but 15 | # WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License along 20 | # with this program; if not, write to the Free Software Foundation, Inc., 21 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | # 23 | # 24 | 25 | export LC_ALL=C 26 | 27 | # ====================================================================== 28 | # CONFIGURATION 29 | # ====================================================================== 30 | export STABLE=${STABLE-master} 31 | export ORIGIN=${ORIGIN-origin} 32 | export VAD_VERSION=${VAD_VERSION-0.1} 33 | # ====================================================================== 34 | 35 | 36 | # 37 | # If we have a local file vad_version then use contents as version 38 | # 39 | VERSION_DIR=`dirname $0` 40 | if test -f "${VERSION_DIR}/vad_version" 41 | then 42 | VAD_VERSION=`cat "${VERSION_DIR}/vad_version"` 43 | fi 44 | 45 | 46 | # 47 | # Check if we are actually inside a git tree, 48 | # else we return whatever version we found so far 49 | # 50 | GIT_DIR=`git rev-parse --git-dir 2>/dev/null || echo does_not_exist` 51 | if test \! -d "$GIT_DIR" 52 | then 53 | echo "ERROR: Not inside a git repository" >&2 54 | echo $VAD_VERSION 55 | exit 1 56 | fi 57 | 58 | 59 | # 60 | # If we use gitflow, we can get the real name for the stable branch 61 | # 62 | export STABLE_BRANCH=`git config gitflow.branch.master || echo ${STABLE}` 63 | 64 | 65 | # 66 | # Get the remote name for the stable branch 67 | # 68 | export STABLE_REMOTE=`git config branch.${STABLE_BRANCH}.remote || echo ${ORIGIN}` 69 | 70 | 71 | # 72 | # If the stable branch can be found, fetch its changes and tags without merging 73 | # else we may end up with the wrong information to calculate the version 74 | # 75 | git show-ref --verify --quiet refs/remotes/${STABLE_REMOTE}/${STABLE_BRANCH} 76 | if test "$?" = "0" 77 | then 78 | git fetch --quiet ${STABLE_REMOTE} ${STABLE} -t 79 | else 80 | echo "Error: Unable to find ${STABLE_REMOTE}/${STABLE_BRANCH}" >&2 81 | echo "VAD_VERSION" 82 | exit 1 83 | fi 84 | 85 | 86 | # 87 | # Get number of commits between stable branch and current HEAD including merge records 88 | # 89 | GIT_V=`git rev-list ${STABLE_REMOTE}/${STABLE}..HEAD | wc -l | sed -e 's/[ \t]*//g'` 90 | if test "$GIT_V" != "0" 91 | then 92 | VAD_VERSION="${VAD_VERSION}_git${GIT_V}" 93 | fi 94 | 95 | echo $VAD_VERSION 96 | 97 | exit 0 98 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config){ 2 | config.set({ 3 | 4 | basePath : './', 5 | 6 | files : [ 7 | 'app/bower_components/angular/angular.js', 8 | 'app/bower_components/angular-route/angular-route.js', 9 | 'app/bower_components/angular-mocks/angular-mocks.js', 10 | 'app/components/**/*.js', 11 | 'app/view*/**/*.js' 12 | ], 13 | 14 | autoWatch : true, 15 | 16 | frameworks: ['jasmine'], 17 | 18 | browsers : ['Chrome'], 19 | 20 | plugins : [ 21 | 'karma-chrome-launcher', 22 | 'karma-firefox-launcher', 23 | 'karma-jasmine', 24 | 'karma-junit-reporter' 25 | ], 26 | 27 | junitReporter : { 28 | outputFile: 'test_out/unit.xml', 29 | suite: 'unit' 30 | } 31 | 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rdf-editor", 3 | "private": true, 4 | "version": "0.18.0", 5 | "description": "OpenLink Structured Data Editor", 6 | "repository": "", 7 | "license": "GPL-2.0", 8 | "devDependencies": { 9 | "grunt": "^1.5.2", 10 | "grunt-autoprefixer": "^3.0.4", 11 | "grunt-concurrent": "^3.0.0", 12 | "grunt-contrib-clean": "^2.0.1", 13 | "grunt-contrib-concat": "^2.1.0", 14 | "grunt-contrib-connect": "^3.0.0", 15 | "grunt-contrib-copy": "^1.0.0", 16 | "grunt-contrib-cssmin": "^4.0.0", 17 | "grunt-contrib-htmlmin": "^3.1.0", 18 | "grunt-contrib-imagemin": "^4.0.0", 19 | "grunt-contrib-jshint": "^3.2.0", 20 | "grunt-contrib-uglify": "^5.2.1", 21 | "grunt-contrib-watch": "^1.1.0", 22 | "grunt-filerev": "^2.1.2", 23 | "grunt-google-cdn": "^0.4.3", 24 | "grunt-karma": "^4.0.2", 25 | "grunt-ng-annotate": "^3.0.0", 26 | "grunt-string-replace": "^1.3.1", 27 | "grunt-svgmin": "^6.0.1", 28 | "grunt-usemin": "^3.1.1", 29 | "grunt-wiredep": "^3.0.1", 30 | "jasmine-core": "^4.1.0", 31 | "jshint-stylish": "^2.2.1", 32 | "karma": "^6.3.19", 33 | "karma-jasmine": "^5.0.0", 34 | "karma-phantomjs-launcher": "^1.0.4", 35 | "load-grunt-tasks": "^5.1.0", 36 | "time-grunt": "^2.0.0" 37 | }, 38 | "engines": { 39 | "node": "^10.x" 40 | }, 41 | "scripts": { 42 | "test": "grunt test" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /rdf-editor-sticker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | '/rdf-editor'); 24 | vhost_define ( 25 | lpath=>'/rdf-editor', 26 | ppath=>'/DAV/VAD/rdf-editor/', 27 | is_dav=>1, 28 | def_page=>'index.html' 29 | ); 30 | ]]> 31 | 32 | 33 | '/rdf-editor'); 35 | ]]> 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/core/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenLink RDF Editor 3 | * 4 | * Copyright (C) 2014-2025 OpenLink Software 5 | * 6 | * This project is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation; only version 2 of the License, dated June 1991. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | */ 20 | 21 | if(!window.RDFE) 22 | window.RDFE = {}; 23 | 24 | /* 25 | * 26 | * Config class 27 | * 28 | */ 29 | RDFE.Config = function(source, callback, fail) { 30 | var self = this; 31 | this.options = RDFE.Config.defaults; 32 | 33 | if (source) { 34 | $.ajax({ 35 | url: source, 36 | type: 'GET', 37 | dataType: 'json', 38 | success: (function(callback) { 39 | return function(data) { 40 | var params = RDFE.Utils.uriParams(); 41 | 42 | self.options = $.extend(self.options, data); 43 | self.options.ontology = $.extend(RDFE.Config.defaults.ontology, data.ontology); 44 | if (params['uiMode'] === 'EAV' || params['uiMode'] === 'SPO') 45 | self.options.namingSchema = params['uiMode']; 46 | 47 | if (!self.options.labelProps || self.options.labelProps.length == 0) 48 | self.options.labelProps = RDFE.Config.defaults.labelProps; 49 | 50 | if (callback) callback(self); 51 | }; 52 | })(callback), 53 | error: function(jqXHR, textStatus, errorThrown) { 54 | console.error('config load =>', errorThrown); 55 | if(fail) { 56 | fail(); 57 | } 58 | } 59 | }); 60 | } 61 | }; 62 | 63 | RDFE.Config.defaults = { 64 | // configuration related to the ontology manager 65 | "ontology": { 66 | "proxy": false, 67 | "nonTTLProxy": true, 68 | "fresnelLenses": true, 69 | "fresnelFormats": true, 70 | "fresnelGroups": true, 71 | "forceLoad": false, 72 | "preloadOnly": false 73 | }, 74 | 75 | // a set of bookmarks which can be loaded from the "bookmarks" action 76 | "bookmarks": [], 77 | 78 | // actions to enable in the UI 79 | "actions": [ 80 | 'new', 81 | 'open', 82 | 'save', 83 | 'saveAs', 84 | 'bookmarks', 85 | 'entities', 86 | 'triples' 87 | ], 88 | 89 | // the properties to use (in order) for fetching resource, class, and property labels 90 | "labelProps": [ 91 | 'http://www.w3.org/2004/02/skos/core#prefLabel', 92 | 'http://www.w3.org/2000/01/rdf-schema#' 93 | ], 94 | 95 | "sparqlEndpoint": window.location.protocol + '//' + window.location.host + '/sparql', 96 | 97 | "gspEndpoint": window.location.protocol + '//' + window.location.host + '/sparql-graph-crud', 98 | 99 | "prefixes": { 100 | }, 101 | 102 | // the template used to create new entity uris. This can contain two variables: 103 | // - {NAME} which is replaced with the entity name/label 104 | // - {DOC-URI} which is replaced with the document URI 105 | // If no variable is included then the entity name will be appended as a fragment 106 | // 107 | // Examples: 108 | // - {DOC-URI}#{NAME} 109 | // - urn:test:{NAME} 110 | "entityUriTmpl": "{DOC-URI}#{NAME}", 111 | 112 | // if true then the editor will take owl:inverseOf into account and create or delete the values properly 113 | "autoInverseOfHandling": false, 114 | 115 | // A list of entity type URIs which when set will be used to filter the entity view 116 | "entityTypesFiler": null, 117 | 118 | // the default view that opens on start ("entities" or "triples") 119 | "defaultView": "statements", 120 | 121 | "namingSchema": "EAV", 122 | "EAV": { 123 | "spo": ["Statement", "Statements"], 124 | "s": ["Entity", "Entities"], 125 | "p": ["Attribute", "Attributes"], 126 | "o": ["Value", "Values"] 127 | }, 128 | "SPO": { 129 | "spo": ["Triple", "Triples"], 130 | "s": ["Subject", "Subjects"], 131 | "p": ["Predicate", "Predicates"], 132 | "o": ["Object", "Objects"] 133 | }, 134 | 135 | // If true, then the entity editor with template and OWL restriction support is used to edit entities 136 | "useEntityEditor": false, 137 | 138 | "maxLabelLength": 0, 139 | 140 | "pageSettings": { 141 | "pageNo": 1, 142 | "pageSize": 10 143 | } 144 | }; 145 | -------------------------------------------------------------------------------- /src/core/rdf_store_ext.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenLink RDF Editor 3 | * 4 | * Copyright (C) 2014-2025 OpenLink Software 5 | * 6 | * This project is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation; only version 2 of the License, dated June 1991. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | */ 20 | 21 | /* Extensions for rdfstore.js */ 22 | /** 23 | * Try to abbreviate a URI using the prefixes defined in the rdfstore. 24 | * @param uri An rdfstore URI node 25 | * @return The abbreviated CURI string or a @p null if no prefix could be found to match the URI. 26 | */ 27 | 28 | /** 29 | * Try to convert an abbreviated CURI into a URI using the prefixes defined in the rdfstore. 30 | * @param curi The abbreviated URI (Example: @p rdf:type) 31 | * @return The full URI if the prefix could be found, @p null otherwise. 32 | */ 33 | rdfstore.Store.prototype.curiToUri = function(curi) { 34 | return this.rdf.resolve(curi); 35 | }; 36 | 37 | rdfstore.Store.prototype.parseLiteral = function(literalString) { 38 | var parts = literalString.lastIndexOf("@"); 39 | if (parts!=-1 && literalString[parts-1]==='"' && literalString.substring(parts, literalString.length).match(/^@[a-zA-Z\-]+$/g)!=null) { 40 | var value = literalString.substring(1,parts-1); 41 | var lang = literalString.substring(parts+1, literalString.length); 42 | return {"token": "literal", "value": value, "lang": lang}; 43 | } 44 | parts = literalString.lastIndexOf("^^"); 45 | if (parts!=-1 && literalString[parts-1]==='"' && literalString[parts+2] === '<' && literalString[literalString.length-1] === '>') { 46 | var value = literalString.substring(1,parts-1); 47 | var type = literalString.substring(parts+3, literalString.length-1); 48 | return {"token": "literal", "value": value, "type": type}; 49 | } 50 | var value = literalString.substring(1,literalString.length-1); 51 | return {"token": "literal", "value": value}; 52 | }; 53 | 54 | 55 | rdfstore.Store.prototype.termToNode = function(term) { 56 | if (term.token == "literal") 57 | return this.rdf.createLiteral(term.value, term.lang, term.type); 58 | 59 | if(term.token == "uri") 60 | return this.rdf.createNamedNode(term.value); 61 | 62 | return this.rdf.createNamedNode(term.value); // FIXME: blank nodes are so much trouble. We need to find a way to handle them properly 63 | }; 64 | 65 | rdfstore.Store.prototype.rdf.api.RDFNode.prototype.localeCompare = function(compareNode, locales, options) { 66 | return this.toString().localeCompare(compareNode.toString(), locales, options); 67 | }; 68 | 69 | rdfstore.Store.prototype.loadTurtle = function(data, graph, baseUri, knownPrefixes, callback) { 70 | var self = this; 71 | var parser = N3.Parser(); 72 | var triples = []; 73 | var blanks = []; 74 | 75 | var convertNode = function(node) { 76 | switch (node[0]) { 77 | case '"': { 78 | if (node.indexOf("^^") > 0) { 79 | var parts = node.split("^^"); 80 | return {"literal": parts[0] + "^^<" + parts[1] + ">" }; 81 | } 82 | return {"literal": node }; 83 | } 84 | case '_': return { blank: node.replace('b', '') }; 85 | default: return { token: 'uri', value: node, prefix: null, suffix: null }; 86 | } 87 | }; 88 | 89 | var convertTriple = function(triple) { 90 | return self.rdf.createTriple(convertNode(triple.subject), convertNode(triple.predicate), convertNode(triple.object)); 91 | }; 92 | 93 | var insertTriples = function() { 94 | try { 95 | self.insert(self.rdf.createGraph(triples), graph, function(error) { 96 | if (error) { 97 | if (callback) { 98 | callback(error); 99 | } 100 | } 101 | else if (blanks.length) { 102 | try { 103 | self.insert(self.rdf.createGraph(blanks), graph, function(error) { 104 | if (error) { 105 | // exec callback (error) function 106 | if (callback) { 107 | callback(error); 108 | } 109 | } 110 | else { 111 | // exec callback (success) function 112 | if (callback) { 113 | callback(null); 114 | } 115 | } 116 | }); 117 | } 118 | catch(e) { 119 | // exec callback (error) function 120 | if (callback) { 121 | callback(e); 122 | } 123 | } 124 | } 125 | else { 126 | // exec callback (success) function 127 | if (callback) { 128 | callback(null); 129 | } 130 | } 131 | }); 132 | } 133 | catch(e) { 134 | // exec callback (error) function 135 | if (callback) { 136 | callback(e); 137 | } 138 | } 139 | }; 140 | 141 | parser.parse(data, function(error, triple, prefixes) { 142 | if (error) { 143 | if (error.message.startsWith('Undefined prefix') && knownPrefixes) { 144 | var ndx = error.message.indexOf('"'); 145 | var prefix = error.message.substring(ndx+1); 146 | ndx = prefix.indexOf('"'); 147 | prefix = prefix.substring(0, ndx-1); 148 | if (knownPrefixes[prefix]) { 149 | data = '@prefix ' + prefix + ': <' + knownPrefixes[prefix] + '> .' + data; 150 | return self.loadTurtle(data, graph, baseUri, knownPrefixes, callback); 151 | } 152 | } 153 | if (callback) { 154 | callback(error); 155 | } 156 | return; 157 | } 158 | if (triple === null) { 159 | insertTriples(); 160 | } 161 | else { 162 | var triple = convertTriple(triple); 163 | if (triple.subject.interfaceName === 'BlankNode' || triple.object.interfaceName === "BlankNode") { 164 | blanks.push(triple); 165 | } 166 | else { 167 | triples.push(triple); 168 | } 169 | } 170 | }); 171 | }; 172 | 173 | RDFModel.Graph.prototype.toNTBeatify = function(prefixes) { 174 | var n3 = ""; 175 | var n3Prefixes = {}; 176 | 177 | this.forEach(function(triple) { 178 | n3 = n3 + triple.toNTBeatify(prefixes, n3Prefixes); 179 | }); 180 | 181 | var p3 = ""; 182 | for (var key in n3Prefixes) { 183 | p3 = p3 + '@prefix ' + key + ': <' + n3Prefixes[key] + '>. \r\n'; 184 | } 185 | 186 | return p3 + '\r\n' + n3; 187 | }; 188 | 189 | RDFModel.NamedNode.prototype.toNTBeatify = function(prefixes, n3Prefixes) { 190 | var x = this.toString(); 191 | for (var prefix in prefixes) { 192 | var ns = prefixes[prefix]; 193 | if (ns.length > 0 && x.startsWith(ns)) { 194 | n3Prefixes[prefix] = ns; 195 | return x.replace(ns, prefix + ':'); 196 | } 197 | } 198 | return "<"+x+">"; 199 | }; 200 | 201 | RDFModel.BlankNode.prototype.toNTBeatify = function() { 202 | return this.toNT(); 203 | }; 204 | 205 | RDFModel.Literal.prototype.toNTBeatify = function() { 206 | return this.toNT(); 207 | }; 208 | 209 | RDFModel.Triple.prototype.toNTBeatify = function(prefixes, n3Prefixes) { 210 | var s = this.subject.toNTBeatify(prefixes, n3Prefixes); 211 | var p = this.predicate.toNTBeatify(prefixes, n3Prefixes); 212 | var o = this.object.toNTBeatify(prefixes, n3Prefixes); 213 | if (p === 'rdf:type') 214 | p = 'a'; 215 | 216 | return s + " " + p + " " + o + " . \r\n"; 217 | }; 218 | -------------------------------------------------------------------------------- /src/core/rdfnode.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenLink RDF Editor 3 | * 4 | * Copyright (C) 2014-2025 OpenLink Software 5 | * 6 | * This project is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation; only version 2 of the License, dated June 1991. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | */ 20 | 21 | if(!window.RDFE) 22 | window.RDFE = {}; 23 | 24 | /** 25 | * The RDFE.RdfNode is a generic representation of an RDF node. URIs and literal are supported. 26 | */ 27 | RDFE.RdfNode = function(t, v, dt, l) { 28 | this.type = t; 29 | this.value = v; 30 | this.datatype = dt; 31 | this.language = l; 32 | }; 33 | 34 | RDFE.RdfNode.prototype.toStoreNode = function(store) { 35 | if(this.type == 'uri') 36 | return store.rdf.createNamedNode(this.value); 37 | 38 | return store.rdf.createLiteral(this.value, this.language, this.datatype); 39 | }; 40 | 41 | RDFE.RdfNode.prototype.toString = function() { 42 | return this.value; 43 | }; 44 | 45 | /** 46 | * Converts a node from rdfstore.js into an RDFE.RdfNode. It tries to be smart. 47 | * @param node The value to be converted. Can be one of: 48 | * - string - will be converted into a URI node. 49 | * - RDFE.RdfNode - will simply be returned 50 | * - rdfstore.js node (RDFJSInterface based or plain) will be converted 51 | * 52 | * Signals an error when encountering a blank node as those are not supported. 53 | */ 54 | RDFE.RdfNode.fromStoreNode = function(node) { 55 | // plain string 56 | if (typeof(node) === 'string') { 57 | return new RDFE.RdfNode('uri', node); 58 | } 59 | 60 | if (typeof(node) === 'number') { 61 | return new RDFE.RdfNode('literal', node); 62 | } 63 | 64 | // already an RdfNode 65 | if (node instanceof RDFE.RdfNode) { 66 | return node; 67 | } 68 | 69 | // rdfstore nodes 70 | if (node.token) { 71 | return new RDFE.RdfNode(node.token, node.value, node.type, node.lang); 72 | } 73 | 74 | // rdfstore.rdf nodes 75 | if (node.interfaceName) { 76 | var t; 77 | 78 | if (node.interfaceName === 'NamedNode') { 79 | t = 'uri'; 80 | } 81 | else if(node.interfaceName === 'Literal') { 82 | t = 'literal' 83 | } 84 | else { 85 | throw "Blank nodes cannot be converted into RDFE.RdfNode values."; 86 | } 87 | return new RDFE.RdfNode(t, node.nominalValue, node.datatype, node.language); 88 | } 89 | 90 | // entities 91 | if (node.uri) { 92 | return new RDFE.RdfNode('uri', node.uri); 93 | } 94 | 95 | // unknown 96 | throw "Unsupported node type for RDFE.RdfNode conversion."; 97 | }; 98 | -------------------------------------------------------------------------------- /src/core/validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenLink RDF Editor 3 | * 4 | * Copyright (C) 2014-2025 OpenLink Software 5 | * 6 | * This project is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation; only version 2 of the License, dated June 1991. 9 | * 10 | * This program is distributed in the hope that it will be useful, but 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | * 19 | */ 20 | 21 | /* 22 | * RDFE Validate functions 23 | */ 24 | if(!window.RDFE) 25 | window.RDFE = {}; 26 | 27 | RDFE.Validate = {}; 28 | 29 | RDFE.Validate.error = function(fld, msg) 30 | { 31 | $.notify({"message": msg}, {"type": 'danger'}); 32 | setTimeout(function(){fld.focus();}, 1); 33 | 34 | return false; 35 | }; 36 | 37 | RDFE.Validate.integer = function(fld, v) 38 | { 39 | var regex = /^[0-9]+$/; 40 | if (!regex.test(v)) 41 | return RDFE.Validate.error(fld, 'Invalid integer value: ' + v); 42 | 43 | return true; 44 | }; 45 | 46 | RDFE.Validate.float = function(fld, v) 47 | { 48 | var regex = /^[-+]?([0-9]*\.)?[0-9]+([eE][-+]?[0-9]+)?$/; 49 | if (!regex.test(v)) 50 | return RDFE.Validate.error(fld, 'Invalid float value: ' + v); 51 | 52 | return true; 53 | }; 54 | 55 | RDFE.Validate.date = function(fld, v) 56 | { 57 | var regex = /^((?:19|20)[0-9][0-9])[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/; 58 | if (!regex.test(v)) 59 | return RDFE.Validate.error(fld, 'Invalid date value: ' + v); 60 | 61 | return true; 62 | }; 63 | 64 | RDFE.Validate.time = function(fld, v) 65 | { 66 | var regex = /^([01]?[0-9]|[2][0-3])(:[0-5][0-9])?$/; 67 | if (!regex.test(v)) 68 | return RDFE.Validate.error(fld, 'Invalid time value: ' + v); 69 | 70 | return true; 71 | }; 72 | 73 | RDFE.Validate.dateTime = function(fld, v) 74 | { 75 | var regex = /^((?:19|20)[0-9][0-9])[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])( ([01]?[0-9]|[2][0-3])(:[0-5][0-9])?)?$/; 76 | if (!regex.test(v)) 77 | return RDFE.Validate.error(fld, 'Invalid date value: ' + v); 78 | 79 | return true; 80 | }; 81 | 82 | RDFE.Validate.mail = function(fld, v) 83 | { 84 | if ((v.length == 0) || (v.length > 40)) 85 | return RDFE.Validate.error(fld, 'E-mail address cannot be empty or longer then 40 chars'); 86 | 87 | var regex = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; 88 | if (!regex.test(v)) 89 | return RDFE.Validate.error(fld, 'Invalid E-mail address: ' + v); 90 | 91 | return true; 92 | }; 93 | 94 | RDFE.Validate.URL = function(fld, v) 95 | { 96 | var regex = /^(ftp|http|https):(\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; 97 | if (!regex.test(v)) 98 | return RDFE.Validate.error(fld, 'Invalid URL address: ' + v); 99 | 100 | return true; 101 | }; 102 | 103 | RDFE.Validate.URI = function(fld, v) 104 | { 105 | var regex = /^([a-z0-9+.-]+):(\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; 106 | var mail = /^acct:([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; 107 | if (!regex.test(v) && !mail.test(v)) 108 | return RDFE.Validate.error(fld, 'Invalid URI address: ' + v); 109 | 110 | return true; 111 | }; 112 | 113 | RDFE.Validate.WebID = function(fld, v) 114 | { 115 | if (v == 'foaf:Agent') 116 | return true; 117 | 118 | var regex = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; 119 | if (regex.test(v)) 120 | return true; 121 | 122 | regex = /^acct:([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-:])+)+\.?([a-zA-Z0-9]{0,4})+$/; 123 | if (regex.test(v)) 124 | return true; 125 | 126 | regex = /^acct:([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; 127 | if (regex.test(v)) 128 | return true; 129 | 130 | return RDFE.Validate.error(fld, 'Invalid URI address: ' + v); 131 | }; 132 | 133 | RDFE.Validate.check = function(fld, v, params) 134 | { 135 | v = RDFE.Utils.trim(v); 136 | params = params || []; 137 | if ((v.length == 0) && (params.indexOf('canEmpty') !== -1)) 138 | return true; 139 | 140 | if (params.indexOf('integer') !== -1) 141 | return RDFE.Validate.integer(fld, v); 142 | 143 | if (params.indexOf('float') !== -1) 144 | return RDFE.Validate.float(fld, v); 145 | 146 | if (params.indexOf('date') !== -1) 147 | return RDFE.Validate.date(fld, v); 148 | 149 | if (params.indexOf('time') !== -1) 150 | return RDFE.Validate.time(fld, v); 151 | 152 | if (params.indexOf('dateTime') !== -1) 153 | return RDFE.Validate.dateTime(fld, v); 154 | 155 | if (params.indexOf('mail') !== -1) 156 | return RDFE.Validate.mail(fld, v); 157 | 158 | if (params.indexOf('URL') !== -1) 159 | return RDFE.Validate.URL(fld, v); 160 | 161 | if (params.indexOf('URI') !== -1) 162 | return RDFE.Validate.URI(fld, v); 163 | 164 | if (params.indexOf('WebID') !== -1) 165 | return RDFE.Validate.WebID(fld, v); 166 | 167 | if (v.length == 0) 168 | return RDFE.Validate.error(fld, 'Field cannot be empty'); 169 | 170 | return true; 171 | }; 172 | -------------------------------------------------------------------------------- /src/deps-demo/bootbox.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * bootbox.js v4.3.0 3 | * 4 | * http://bootboxjs.com/license.txt 5 | */ 6 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d(a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),a.backdrop=a.backdrop?"static":!1,c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"",header:"",footer:"",closeButton:"",form:"
",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"
",date:"",time:"",number:"",password:""}},o={locale:"en",backdrop:!0,animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback():!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback(!1)},a.buttons.confirm.callback=function(){return a.callback(!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback(null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback(c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("").attr("label",d.group)),e=o[d.group]),e.append("")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("
"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var c=b(n.dialog),d=c.find(".modal-dialog"),f=c.find(".modal-body"),i=a.buttons,j="",k={onEscape:a.onEscape};if(g(i,function(a,b){j+="",k[a]=b.callback}),f.find(".bootbox-body").html(a.message),a.animate===!0&&c.addClass("fade"),a.className&&c.addClass(a.className),"large"===a.size&&d.addClass("modal-lg"),"small"===a.size&&d.addClass("modal-sm"),a.title&&f.before(n.header),a.closeButton){var l=b(n.closeButton);a.title?c.find(".modal-header").prepend(l):l.css("margin-top","-10px").prependTo(f)}return a.title&&c.find(".modal-title").html(a.title),j.length&&(f.after(n.footer),c.find(".modal-footer").html(j)),c.on("hidden.bs.modal",function(a){a.target===this&&c.remove()}),c.on("shown.bs.modal",function(){c.find(".btn-primary:first").focus()}),c.on("escape.close.bb",function(a){k.onEscape&&e(a,c,k.onEscape)}),c.on("click",".modal-footer button",function(a){var d=b(this).data("bb-handler");e(a,c,k[d])}),c.on("click",".bootbox-close-button",function(a){e(a,c,k.onEscape)}),c.on("keyup",function(a){27===a.which&&c.trigger("escape.close.bb")}),b(a.container).append(c),c.modal({backdrop:a.backdrop,keyboard:!1,show:!1}),a.show&&c.modal("show"),c},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.init=function(c){return a(c||b)},p}); -------------------------------------------------------------------------------- /src/deps-demo/bootstrap-notify.min.js: -------------------------------------------------------------------------------- 1 | !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t("object"==typeof exports?require("jquery"):jQuery)}(function(t){function s(s){var e=!1;return t('[data-notify="container"]').each(function(i,n){var a=t(n),o=a.find('[data-notify="title"]').text().trim(),r=a.find('[data-notify="message"]').html().trim(),l=o===t("
"+s.settings.content.title+"
").html().trim(),d=r===t("
"+s.settings.content.message+"
").html().trim(),g=a.hasClass("alert-"+s.settings.type);return l&&d&&g&&(e=!0),!e}),e}function e(e,n,a){var o={content:{message:"object"==typeof n?n.message:n,title:n.title?n.title:"",icon:n.icon?n.icon:"",url:n.url?n.url:"#",target:n.target?n.target:"-"}};a=t.extend(!0,{},o,a),this.settings=t.extend(!0,{},i,a),this._defaults=i,"-"===this.settings.content.target&&(this.settings.content.target=this.settings.url_target),this.animations={start:"webkitAnimationStart oanimationstart MSAnimationStart animationstart",end:"webkitAnimationEnd oanimationend MSAnimationEnd animationend"},"number"==typeof this.settings.offset&&(this.settings.offset={x:this.settings.offset,y:this.settings.offset}),(this.settings.allow_duplicates||!this.settings.allow_duplicates&&!s(this))&&this.init()}var i={element:"body",position:null,type:"info",allow_dismiss:!0,allow_duplicates:!0,newest_on_top:!1,showProgressbar:!1,placement:{from:"top",align:"right"},offset:20,spacing:10,z_index:1031,delay:5e3,timer:1e3,url_target:"_blank",mouse_over:null,animate:{enter:"animated fadeInDown",exit:"animated fadeOutUp"},onShow:null,onShown:null,onClose:null,onClosed:null,icon_type:"class",template:''};String.format=function(){for(var t=arguments[0],s=1;s .progress-bar').removeClass("progress-bar-"+t.settings.type),t.settings.type=i[n],this.$ele.addClass("alert-"+i[n]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-"+i[n]);break;case"icon":var a=this.$ele.find('[data-notify="icon"]');"class"===t.settings.icon_type.toLowerCase()?a.removeClass(t.settings.content.icon).addClass(i[n]):(a.is("img")||a.find("img"),a.attr("src",i[n]));break;case"progress":var o=t.settings.delay-t.settings.delay*(i[n]/100);this.$ele.data("notify-delay",o),this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i[n]).css("width",i[n]+"%");break;case"url":this.$ele.find('[data-notify="url"]').attr("href",i[n]);break;case"target":this.$ele.find('[data-notify="url"]').attr("target",i[n]);break;default:this.$ele.find('[data-notify="'+n+'"]').html(i[n])}var r=this.$ele.outerHeight()+parseInt(t.settings.spacing)+parseInt(t.settings.offset.y);t.reposition(r)},close:function(){t.close()}}},buildNotify:function(){var s=this.settings.content;this.$ele=t(String.format(this.settings.template,this.settings.type,s.title,s.message,s.url,s.target)),this.$ele.attr("data-notify-position",this.settings.placement.from+"-"+this.settings.placement.align),this.settings.allow_dismiss||this.$ele.find('[data-notify="dismiss"]').css("display","none"),(this.settings.delay<=0&&!this.settings.showProgressbar||!this.settings.showProgressbar)&&this.$ele.find('[data-notify="progressbar"]').remove()},setIcon:function(){"class"===this.settings.icon_type.toLowerCase()?this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon):this.$ele.find('[data-notify="icon"]').is("img")?this.$ele.find('[data-notify="icon"]').attr("src",this.settings.content.icon):this.$ele.find('[data-notify="icon"]').append('Notify Icon')},styleDismiss:function(){this.$ele.find('[data-notify="dismiss"]').css({position:"absolute",right:"10px",top:"5px",zIndex:this.settings.z_index+2})},styleURL:function(){this.$ele.find('[data-notify="url"]').css({backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)",height:"100%",left:0,position:"absolute",top:0,width:"100%",zIndex:this.settings.z_index+1})},placement:function(){var s=this,e=this.settings.offset.y,i={display:"inline-block",margin:"0px auto",position:this.settings.position?this.settings.position:"body"===this.settings.element?"fixed":"absolute",transition:"all .5s ease-in-out",zIndex:this.settings.z_index},n=!1,a=this.settings;switch(t('[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])').each(function(){e=Math.max(e,parseInt(t(this).css(a.placement.from))+parseInt(t(this).outerHeight())+parseInt(a.spacing))}),this.settings.newest_on_top===!0&&(e=this.settings.offset.y),i[this.settings.placement.from]=e+"px",this.settings.placement.align){case"left":case"right":i[this.settings.placement.align]=this.settings.offset.x+"px";break;case"center":i.left=0,i.right=0}this.$ele.css(i).addClass(this.settings.animate.enter),t.each(Array("webkit-","moz-","o-","ms-",""),function(t,e){s.$ele[0].style[e+"AnimationIterationCount"]=1}),t(this.settings.element).append(this.$ele),this.settings.newest_on_top===!0&&(e=parseInt(e)+parseInt(this.settings.spacing)+this.$ele.outerHeight(),this.reposition(e)),t.isFunction(s.settings.onShow)&&s.settings.onShow.call(this.$ele),this.$ele.one(this.animations.start,function(){n=!0}).one(this.animations.end,function(){s.$ele.removeClass(s.settings.animate.enter),t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)}),setTimeout(function(){n||t.isFunction(s.settings.onShown)&&s.settings.onShown.call(this)},600)},bind:function(){var s=this;if(this.$ele.find('[data-notify="dismiss"]').on("click",function(){s.close()}),this.$ele.mouseover(function(){t(this).data("data-hover","true")}).mouseout(function(){t(this).data("data-hover","false")}),this.$ele.data("data-hover","false"),this.settings.delay>0){s.$ele.data("notify-delay",s.settings.delay);var e=setInterval(function(){var t=parseInt(s.$ele.data("notify-delay"))-s.settings.timer;if("false"===s.$ele.data("data-hover")&&"pause"===s.settings.mouse_over||"pause"!=s.settings.mouse_over){var i=(s.settings.delay-t)/s.settings.delay*100;s.$ele.data("notify-delay",t),s.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow",i).css("width",i+"%")}t<=-s.settings.timer&&(clearInterval(e),s.close())},s.settings.timer)}},close:function(){var s=this,e=parseInt(this.$ele.css(this.settings.placement.from)),i=!1;this.$ele.attr("data-closing","true").addClass(this.settings.animate.exit),s.reposition(e),t.isFunction(s.settings.onClose)&&s.settings.onClose.call(this.$ele),this.$ele.one(this.animations.start,function(){i=!0}).one(this.animations.end,function(){t(this).remove(),t.isFunction(s.settings.onClosed)&&s.settings.onClosed.call(this)}),setTimeout(function(){i||(s.$ele.remove(),s.settings.onClosed&&s.settings.onClosed(s.$ele))},600)},reposition:function(s){var e=this,i='[data-notify-position="'+this.settings.placement.from+"-"+this.settings.placement.align+'"]:not([data-closing="true"])',n=this.$ele.nextAll(i);this.settings.newest_on_top===!0&&(n=this.$ele.prevAll(i)),n.each(function(){t(this).css(e.settings.placement.from,s),s=parseInt(s)+parseInt(e.settings.spacing)+t(this).outerHeight()})}}),t.notify=function(t,s){var i=new e(this,t,s);return i.notify},t.notifyDefaults=function(s){return i=t.extend(!0,{},i,s)},t.notifyClose=function(s){"warning"===s&&(s="danger"),"undefined"==typeof s||"all"===s?t("[data-notify]").find('[data-notify="dismiss"]').trigger("click"):"success"===s||"info"===s||"warning"===s||"danger"===s?t(".alert-"+s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):s?t(s+"[data-notify]").find('[data-notify="dismiss"]').trigger("click"):t('[data-notify-position="'+s+'"]').find('[data-notify="dismiss"]').trigger("click")},t.notifyCloseExcept=function(s){"warning"===s&&(s="danger"),"success"===s||"info"===s||"warning"===s||"danger"===s?t("[data-notify]").not(".alert-"+s).find('[data-notify="dismiss"]').trigger("click"):t("[data-notify]").not(s).find('[data-notify="dismiss"]').trigger("click")}}); -------------------------------------------------------------------------------- /src/deps-demo/dummy.js: -------------------------------------------------------------------------------- 1 | ; 2 | -------------------------------------------------------------------------------- /src/deps-demo/jquery-deparam.min.js: -------------------------------------------------------------------------------- 1 | (function(h){h.deparam=function(i,j){var d={},k={"true":!0,"false":!1,"null":null};h.each(i.replace(/\+/g," ").split("&"),function(i,l){var m;var a=l.split("="),c=decodeURIComponent(a[0]),g=d,f=0,b=c.split("]["),e=b.length-1;/\[/.test(b[0])&&/\]$/.test(b[e])?(b[e]=b[e].replace(/\]$/,""),b=b.shift().split("[").concat(b),e=b.length-1):e=0;if(2===a.length)if(a=decodeURIComponent(a[1]),j&&(a=a&&!isNaN(a)?+a:"undefined"===a?void 0:void 0!==k[a]?k[a]:a),e)for(;f<=e;f++)c=""===b[f]?g.length:b[f],m=g[c]= 2 | f').html(this.options.on).addClass(this._onstyle+" "+b),d=a('