]");
7 | console.log("Example: phantomjs build.js ../demo/examples/mods.js ../demo/examples/mods-3-4/ mods-3-4.xsd modsSchema");
8 | phantom.exit(1);
9 | }
10 |
11 | var output = system.args[1];
12 | // This is the directory where all it will attempt to find all referenced schemas first before trying any URLs
13 | var schemaPath = null;
14 | if (system.args.length > 2) {
15 | schemaPath = system.args[2];
16 | } else {
17 | schemaPath = "./";
18 | }
19 | // The filename of the first schema to process
20 | var baseSchema;
21 | if (system.args.length > 3) {
22 | baseSchema = system.args[3];
23 | } else {
24 | baseSchema = "*.xsd";
25 | }
26 | // Name of the JSON variable constructed from this schema
27 | var variableName = null;
28 | if (system.args.length > 4) {
29 | variableName = system.args[4];
30 | }
31 |
32 | page.open("./build.html", function() {
33 | var json = page.evaluate(function(schemaPath, baseSchema) {
34 | var options = {
35 | 'schemaURI': schemaPath
36 | }
37 |
38 | var extractor = new Xsd2Json(baseSchema, options);
39 |
40 | return extractor.stringify();
41 | }, schemaPath, baseSchema);
42 |
43 | if (json) {
44 | if (variableName != null)
45 | json = "var " + variableName + " = " + json + ";";
46 | if (output)
47 | fs.write(output, json, "w");
48 | else
49 | console.log(json);
50 | } else
51 | console.error("null result from script evaluation");
52 |
53 | phantom.exit();
54 |
55 | });
56 |
--------------------------------------------------------------------------------
/demo/examples/dcterms/dcmitype.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMI Type Vocabulary XML Schema
11 | XML Schema for http://purl.org/dc/dcmitype/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema defines a simpleType which enumerates
24 | the allowable values for the DCMI Type Vocabulary.
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/tests/issue-078-dcterms/dcmitype.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMI Type Vocabulary XML Schema
11 | XML Schema for http://purl.org/dc/dcmitype/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema defines a simpleType which enumerates
24 | the allowable values for the DCMI Type Vocabulary.
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/demo/stylesheets/reset.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2008 The University of North Carolina at Chapel Hill
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | /* Eric Meyer's Reset Reloaded
17 | Accessed 3/1/10
18 | http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
19 | */
20 |
21 | html, body, div, span, applet, object, iframe,
22 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
23 | a, abbr, acronym, address, big, cite, code,
24 | del, dfn, em, font, img, ins, kbd, q, s, samp,
25 | small, strike, strong, sub, sup, tt, var,
26 | dl, dt, dd, ol, ul, li,
27 | fieldset, form, label, legend,
28 | table, caption, tbody, tfoot, thead, tr, th, td {
29 | margin: 0;
30 | padding: 0;
31 | border: 0;
32 | outline: 0;
33 | font-weight: inherit;
34 | font-style: inherit;
35 | font-size: 100%;
36 | font-family: inherit;
37 | vertical-align: baseline;
38 | }
39 | /* remember to define focus styles! */
40 | :focus {
41 | outline: 0;
42 | }
43 | body {
44 | line-height: 1;
45 | color: black;
46 | background: white;
47 | }
48 | ol, ul {
49 | list-style: none;
50 | }
51 | /* tables still need 'cellspacing="0"' in the markup */
52 | table {
53 | border-collapse: separate;
54 | border-spacing: 0;
55 | }
56 | caption, th, td {
57 | text-align: left;
58 | font-weight: normal;
59 | }
60 | blockquote:before, blockquote:after,
61 | q:before, q:after {
62 | content: "";
63 | }
64 | blockquote, q {
65 | quotes: "" "";
66 | }
--------------------------------------------------------------------------------
/demo/relator.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
26 | <mods xmlns="http://www.loc.gov/mods/v3">
27 | <name>
28 | <role>
29 | <roleTerm />
30 | </role>
31 | </name>
32 | </mods>
33 |
34 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/demo/stylesheets/demo.css:
--------------------------------------------------------------------------------
1 | header {
2 | margin-bottom: 15px;
3 | }
4 |
5 | header h1, header h2, header h3, header h4, header h5, header h6 {
6 | color:#222;
7 | margin:0 0 20px;
8 | }
9 |
10 | header p, header ul, header ol, header table, header pre, header dl {
11 | margin:0 0 20px;
12 | }
13 |
14 | header h1, header h2, header h3 {
15 | line-height:1.1;
16 | }
17 |
18 | header h1 {
19 | font-size:28px;
20 | }
21 |
22 | header h2 {
23 | color:#393939;
24 | }
25 |
26 | header h3, header h4, header h5, header h6 {
27 | color:#494949;
28 | }
29 |
30 | header ul li + li {
31 | width:88px;
32 | border-left:1px solid #fff;
33 | }
34 |
35 | header ul li + li + li {
36 | border-right:none;
37 | width:89px;
38 | }
39 |
40 | header ul a strong {
41 | font-size:14px;
42 | display:block;
43 | color:#222;
44 | }
45 | header ul {
46 | list-style:none;
47 | height:40px;
48 |
49 | padding:0;
50 |
51 | background: #eee;
52 | background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%);
53 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd));
54 | background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
55 | background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
56 | background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
57 | background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%);
58 |
59 | border-radius:5px;
60 | border:1px solid #d2d2d2;
61 | box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;
62 | width:270px;
63 | }
64 |
65 | header li {
66 | width:89px;
67 | float:left;
68 | border-right:1px solid #d2d2d2;
69 | height:40px;
70 | }
71 |
72 | header ul a {
73 | line-height:1;
74 | font-size:11px;
75 | color:#999;
76 | display:block;
77 | text-align:center;
78 | padding-top:6px;
79 | height:40px;
80 | text-decoration: none;
81 | }
82 |
83 | header .view a {
84 | color: #39C;
85 | text-decoration: none;
86 | font-weight: 400px;
87 | }
88 |
89 | body {
90 | padding: 20px;
91 | color: #777195;
92 | }
93 |
94 | #xml_editor {
95 | font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
96 | font-size: 14px;
97 | background-color: #fff;
98 | }
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | var runTest = function(name) {
3 | var schema = new Xsd2Json('schema.xsd', {schemaURI: name + '/'}).getSchema()();
4 | var rawExpectedSchema;
5 | $.ajax({
6 | url: name + '/schema.json',
7 | async: false
8 | }).done(function(data) {
9 | rawExpectedSchema = data;
10 | });
11 | var expectedSchema = JSON.retrocycle(rawExpectedSchema);
12 | if (!_.isEqual(schema, expectedSchema)) {
13 | console.log(name, 'result', schema, 'expected', expectedSchema);
14 | throw Error('Wrong result schema');
15 | }
16 | };
17 | var getTestcases = function() {
18 | var responseData;
19 | $.ajax({
20 | url: 'tests.json',
21 | async: false
22 | }).done(function(data) {
23 | responseData = data;
24 | });
25 | return responseData.testcases;
26 | };
27 | var buildTestcasesTable = function(testcases) {
28 | testcases.forEach(function(name) {
29 | var tr = $(' | |
');
30 | var a = tr.find('a');
31 | a.text(name);
32 | var m = name.match(/^issue-([0-9]+)/);
33 | if (m !== null) {
34 | var issue = m[1];
35 | a.attr('href', 'https://github.com/UNC-Libraries/jquery.xmleditor/issues/' + issue);
36 | }
37 | tr.appendTo($('.testcases'));
38 | });
39 | };
40 | var main = function() {
41 | var testcases = getTestcases();
42 | var totalCount = testcases.length;
43 | var okCount = 0;
44 | $('.totalCount').text(totalCount);
45 | buildTestcasesTable(testcases);
46 | $('.testcases tr').each(function(i, tr) {
47 | var name = $(tr).find('a').text();
48 | var ok = false;
49 | var errorMessage = '';
50 | try {
51 | runTest(name);
52 | ok = true;
53 | } catch (e) {
54 | errorMessage = e.message;
55 | }
56 | $(tr).addClass(ok ? 'ok' : 'failure');
57 | $(tr).find('td').text(ok ? 'OK' : errorMessage);
58 | if (ok) {
59 | okCount++;
60 | }
61 | });
62 | var failCount = totalCount - okCount;
63 | $('.okCount').text(okCount);
64 | $('.failCount').text(failCount);
65 | $('.summary').addClass(failCount === 0 ? 'ok' : 'failure');
66 | };
67 | main();
68 | });
69 |
--------------------------------------------------------------------------------
/demo/cpf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 | EAC-CPF Example with Language Autocomplete
25 | Language suggestions in: control > languageDeclaration > language
26 |
27 | <eac-cpf xmlns="urn:isbn:1-931666-33-4">
28 | <control>
29 | <languageDeclaration>
30 | <language />
31 | </languageDeclaration>
32 | </control>
33 | </eac-cpf>
34 |
35 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/xml_cdata_node.js:
--------------------------------------------------------------------------------
1 | function XMLCDataNode(cdataNode, editor) {
2 | var nodeType = {
3 | cdata : true,
4 | type : "cdata"
5 | };
6 |
7 | XMLTextNode.call(this, cdataNode, nodeType, editor);
8 |
9 | this.objectType = nodeType;
10 | }
11 |
12 | XMLCDataNode.prototype.constructor = XMLCDataNode;
13 | XMLCDataNode.prototype = Object.create( XMLTextNode.prototype );
14 |
15 | XMLCDataNode.prototype.addXmlNode = function(prepend) {
16 | var textValue = "";
17 | if (!this.textNode) {
18 | var parentNode = this.parentElement.xmlNode;
19 | this.textNode = parentNode[0].ownerDocument.createCDATASection("");
20 | if (prepend) {
21 | parentNode.prepend(this.textNode);
22 | } else {
23 | parentNode[0].appendChild(this.textNode);
24 | }
25 | this.xmlNode = $(this.textNode);
26 | } else {
27 | textValue = this.textNode.nodeValue;
28 | }
29 | return textValue;
30 | };
31 |
32 | XMLCDataNode.prototype.render = function(parentElement, prepend) {
33 | XMLTextNode.prototype.render.call(this, parentElement, prepend);
34 | this.domNode.addClass("xml_cdata_node");
35 |
36 | var header = document.createElement('label');
37 | header.className = 'xml_type_header';
38 | header.appendChild(document.createTextNode('CDATA'));
39 | $(header).attr("for", this.domNodeID + "_text");
40 |
41 | this.domNode.children(".xml_input_column").prepend(header);
42 | };
43 |
44 | // Persist the input value back into the text node
45 | XMLCDataNode.prototype.syncText = function() {
46 | XMLTextNode.prototype.syncText.call(this);
47 | };
48 |
49 | XMLCDataNode.prototype.remove = function() {
50 | AbstractXMLObject.prototype.remove.call(this);
51 | };
52 |
53 | XMLCDataNode.prototype.select = function() {
54 | XMLTextNode.prototype.select.call(this);
55 | };
56 |
57 | XMLCDataNode.prototype.swap = function(swapTarget) {
58 | AbstractXMLObject.prototype.swap.call(this, swapTarget);
59 | };
60 |
61 | XMLCDataNode.prototype.moveUp = function() {
62 | AbstractXMLObject.prototype.moveUp.call(this);
63 | };
64 |
65 | XMLCDataNode.prototype.moveDown = function() {
66 | AbstractXMLObject.prototype.moveDown.call(this);
67 | };
68 |
69 | XMLCDataNode.prototype.focus = function() {
70 | AbstractXMLObject.prototype.focus.call(this);
71 | };
72 |
73 | XMLCDataNode.prototype.isSelected = function() {
74 | return AbstractXMLObject.prototype.isSelected.call(this);
75 | };
--------------------------------------------------------------------------------
/src/xml_attribute_stub.js:
--------------------------------------------------------------------------------
1 | function XMLAttributeStub(xmlElement, editor) {
2 | this.objectType = {
3 | attrStub : true
4 | };
5 | this.editor = editor;
6 | this.guiEditor = this.editor.guiEditor;
7 | // dom element header for this element
8 | this.elementHeader = null;
9 | this.tagName = "";
10 |
11 | this.xmlElement = xmlElement;
12 |
13 | this.nameInput = null;
14 | }
15 |
16 | XMLAttributeStub.prototype.render = function() {
17 | this.domNodeID = "attr_stub_" + this.guiEditor.nextIndex();
18 |
19 | this.domNode = $("").attr({
20 | 'id' : this.domNodeID + "_cont",
21 | 'class' : attributeContainerClass + " xml_attr_stub"
22 | }).data('xmlAttribute', this).appendTo(this.xmlElement.getAttributeContainer());
23 |
24 | var self = this;
25 | var removeButton = document.createElement('a');
26 | removeButton.appendChild(document.createTextNode('(x) '));
27 | this.domNode[0].appendChild(removeButton);
28 |
29 | this.nameInput = document.createElement('label');
30 | this.nameInput.className = "edit_title";
31 | this.nameInput.setAttribute("contenteditable", "true");
32 | this.domNode[0].appendChild(this.nameInput);
33 | this.nameInput = $(this.nameInput);
34 |
35 | var createLink = $("create attribute").appendTo(this.domNode).mouseup(function(e){
36 | self.create();
37 | });
38 |
39 | stubNameInput.call(this, this.nameInput, this.xmlElement.objectType.attributes,
40 | $.proxy(this.xmlElement.attributeExists, this.xmlElement));
41 |
42 | return this.domNode;
43 | };
44 |
45 | XMLAttributeStub.prototype.remove = function() {
46 | this.domNode.remove();
47 | };
48 |
49 | XMLAttributeStub.prototype.create = function() {
50 | var attrName = this.nameInput.text();
51 | var newAttr = this.editor.addAttribute(this.xmlElement, attrName);
52 |
53 | if (newAttr instanceof AbstractXMLObject) {
54 | this.remove();
55 | } else {
56 | console.log(newAttr);
57 | }
58 | };
59 |
60 | XMLAttributeStub.prototype.select = function() {
61 | this.domNode.addClass("selected");
62 | };
63 |
64 | XMLAttributeStub.prototype.deselect = function() {
65 | this.domNode.removeClass('selected');
66 | };
67 |
68 | XMLAttributeStub.prototype.isSelected = function() {
69 | return this.domNode.hasClass("selected");
70 | };
71 |
72 | XMLAttributeStub.prototype.focus = function() {
73 | this.nameInput.focus();
74 | };
75 |
--------------------------------------------------------------------------------
/src/xml_comment_node.js:
--------------------------------------------------------------------------------
1 | function XMLCommentNode(cdataNode, editor) {
2 | var nodeType = {
3 | comment : true,
4 | type : "comment"
5 | };
6 |
7 | XMLTextNode.call(this, cdataNode, nodeType, editor);
8 |
9 | this.objectType = nodeType;
10 | }
11 |
12 | XMLCommentNode.prototype.constructor = XMLCommentNode;
13 | XMLCommentNode.prototype = Object.create( XMLTextNode.prototype );
14 |
15 | XMLCommentNode.prototype.addXmlNode = function(prepend) {
16 | var textValue = "";
17 | if (!this.textNode) {
18 | var parentNode = this.parentElement.xmlNode;
19 | this.textNode = parentNode[0].ownerDocument.createComment("");
20 | if (prepend) {
21 | parentNode.prepend(this.textNode);
22 | } else {
23 | parentNode[0].appendChild(this.textNode);
24 | }
25 | this.xmlNode = $(this.textNode);
26 | } else {
27 | textValue = this.textNode.nodeValue;
28 | }
29 | return textValue;
30 | };
31 |
32 | XMLCommentNode.prototype.render = function(parentElement, prepend) {
33 | XMLTextNode.prototype.render.call(this, parentElement, prepend);
34 | this.domNode.addClass("xml_comment_node");
35 |
36 | var header = document.createElement('label');
37 | header.className = 'xml_type_header';
38 | header.appendChild(document.createTextNode('comment'));
39 | $(header).attr("for", this.domNodeID + "_text");
40 |
41 | this.domNode.children(".xml_input_column").prepend(header);
42 | };
43 |
44 | // Persist the input value back into the text node
45 | XMLCommentNode.prototype.syncText = function() {
46 | XMLTextNode.prototype.syncText.call(this);
47 | };
48 |
49 | XMLCommentNode.prototype.remove = function() {
50 | AbstractXMLObject.prototype.remove.call(this);
51 | };
52 |
53 | XMLCommentNode.prototype.select = function() {
54 | XMLTextNode.prototype.select.call(this);
55 | };
56 |
57 | XMLCommentNode.prototype.swap = function(swapTarget) {
58 | AbstractXMLObject.prototype.swap.call(this, swapTarget);
59 | };
60 |
61 | XMLCommentNode.prototype.moveUp = function() {
62 | AbstractXMLObject.prototype.moveUp.call(this);
63 | };
64 |
65 | XMLCommentNode.prototype.moveDown = function() {
66 | AbstractXMLObject.prototype.moveDown.call(this);
67 | };
68 |
69 | XMLCommentNode.prototype.focus = function() {
70 | AbstractXMLObject.prototype.focus.call(this);
71 | };
72 |
73 | XMLCommentNode.prototype.isSelected = function() {
74 | return AbstractXMLObject.prototype.isSelected.call(this);
75 | };
--------------------------------------------------------------------------------
/demo/templates.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jQuery.xmleditor
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
26 |
27 |
28 |
29 |
37 |
38 |
39 |
58 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/demo/atom.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Atom example
19 |
57 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/format_xml.js:
--------------------------------------------------------------------------------
1 | var XML_CHAR_MAP = {
2 | '<': '<',
3 | '>': '>',
4 | '&': '&',
5 | '"': '"',
6 | "'": '''
7 | };
8 |
9 | function escapeXml (s) {
10 | return s.replace(/[<>&"']/g, function (ch) {
11 | return XML_CHAR_MAP[ch];
12 | });
13 | }
14 |
15 | function formatXML(element, indent, options) {
16 |
17 | var children = element.childNodes;
18 | var prevNode = null;
19 | var whitespace = "";
20 | var containsText = false;
21 |
22 | var contents = "";
23 | var attrContents = "";
24 |
25 | for (var index in children) {
26 | var childNode = children[index]
27 | switch (childNode.nodeType) {
28 | case 1 : // element
29 | var tagIndent = "";
30 | var nextIndent = "";
31 | if (!containsText) {
32 | if (element.nodeType != 9) {
33 | nextIndent = indent + " ";
34 | tagIndent = "\n";
35 | }
36 | }
37 |
38 | contents += tagIndent + formatXML(childNode, nextIndent, options);
39 | containsText = false;
40 | break;
41 | case 3 : // text
42 | var value = childNode.nodeValue;
43 | if ($.trim(value)) {
44 | contents += whitespace + escapeXml(value);
45 | whitespace = "";
46 | containsText = true;
47 | } else {
48 | whitespace = value;
49 | }
50 | break;
51 | case 4 : // cdata
52 | if (!containsText) {
53 | if (element.nodeType != 9) {
54 | contents += "\n" + indent + " ";
55 | }
56 | }
57 | contents += "";
58 | break;
59 | case 8 : // comment
60 | if (!containsText) {
61 | if (element.nodeType != 9) {
62 | contents += "\n" + indent + " ";
63 | }
64 | }
65 | contents += "";
66 | break;
67 | }
68 |
69 | prevNode = childNode;
70 | }
71 |
72 | var attributes = element.attributes;
73 | if (attributes) {
74 | var xmlnsPattern = /^xmlns:?(.*)$/;
75 | var previousWasNS = false;
76 | for (var index = 0; index < attributes.length; index++) {
77 | if (previousWasNS) {
78 | attrContents += "\n" + indent + " ";
79 | previousWasNS = false;
80 | }
81 | attrContents += " " + attributes[index].nodeName + '="' + escapeXml(attributes[index].nodeValue) +'"';
82 | if (xmlnsPattern.test(attributes[index].nodeName))
83 | previousWasNS = true;
84 | }
85 | }
86 |
87 | if (element.nodeType == 1) {
88 | if (contents) {
89 | var closingIndent = (!containsText)? "\n" + indent : "";
90 | return indent + "<" + element.nodeName + attrContents + ">" + contents + closingIndent + "" + element.nodeName + ">";
91 | } else {
92 | return indent + "<" + element.nodeName + attrContents + " />";
93 | }
94 | } else {
95 | return contents;
96 | }
97 |
98 | }
--------------------------------------------------------------------------------
/src/attribute_menu.js:
--------------------------------------------------------------------------------
1 | function AttributeMenu(menuID, label, expanded, enabled, owner, editor) {
2 | ModifyElementMenu.call(this, menuID, label, expanded, enabled, owner, editor);
3 | }
4 |
5 | AttributeMenu.prototype.constructor = AttributeMenu;
6 | AttributeMenu.prototype = Object.create( ModifyElementMenu.prototype );
7 |
8 | AttributeMenu.prototype.initEventHandlers = function() {
9 | var self = this;
10 | this.menuContent.on('click', 'li', function(event){
11 | self.owner.editor.addAttributeButtonCallback(this);
12 | });
13 | };
14 |
15 | AttributeMenu.prototype.populate = function (xmlElement) {
16 | if (xmlElement == null || (this.target != null && xmlElement.domNode != null
17 | && this.target[0] === xmlElement.domNode[0]))
18 | return;
19 |
20 | if (this.expanded)
21 | this.menuContent.css("height", "auto");
22 | var startingHeight = this.menuContent.outerHeight();
23 | this.menuContent.empty();
24 |
25 | this.target = xmlElement;
26 |
27 | var attributesArray = this.target.objectType.attributes;
28 | if (attributesArray) {
29 | var attributesPresent = {};
30 | $(this.target.xmlNode[0].attributes).each(function() {
31 | var targetAttribute = this;
32 | $.each(attributesArray, function(){
33 | if (this.name == targetAttribute.nodeName) {
34 | attributesPresent[this.name] = $("#" + xmlElement.domNodeID + "_" + targetAttribute.nodeName.replace(':', '-'));
35 | }
36 | });
37 | });
38 |
39 | var self = this;
40 | $.each(this.target.objectType.attributes, function(){
41 | var attribute = this;
42 | // Using prefix according to the xml document namespace prefixes
43 | var nsPrefix = self.editor.xmlState.getNamespacePrefix(attribute.namespace);
44 |
45 | var attrName = nsPrefix + attribute.localName;
46 | var addButton = $("").attr({
47 | title : 'Add ' + attrName,
48 | 'id' : xmlElement.domNodeID + "_" + attrName.replace(":", "_") + "_add"
49 | }).html(attrName)
50 | .data('xml', {
51 | "objectType": attribute,
52 | "target": xmlElement
53 | }).appendTo(self.menuContent);
54 |
55 | if (attribute.name in attributesPresent) {
56 | addButton.addClass("disabled");
57 | if (attributesPresent[attribute.name].length > 0)
58 | attributesPresent[attribute.name].data('xmlAttribute').addButton = addButton;
59 | }
60 | });
61 | }
62 |
63 | if (this.expanded) {
64 | var endingHeight = this.menuContent.outerHeight();
65 | if (endingHeight == 0)
66 | endingHeight = 1;
67 | this.menuContent.css({height: startingHeight + "px"}).stop().animate({height: endingHeight + "px"}, menuExpandDuration).show();
68 | }
69 |
70 | if (this.menuContent.children().length == 0) {
71 | this.menuHeader.addClass("disabled");
72 | this.enabled = false;
73 | } else {
74 | this.menuHeader.removeClass("disabled");
75 | this.enabled = true;
76 | }
77 |
78 | return this;
79 | };
80 |
--------------------------------------------------------------------------------
/lib/jquery.autosize-min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | jQuery Autosize v1.16.20
3 | (c) 2013 Jack Moore - jacklmoore.com
4 | updated: 2013-06-18
5 | license: http://www.opensource.org/licenses/mit-license.php
6 | */
7 | (function(e){var t,o={className:"autosizejs",append:"",callback:!1,resizeDelay:10},i='',n=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],s=e(i).data("autosize",!0)[0];s.style.lineHeight="99px","99px"===e(s).css("lineHeight")&&n.push("lineHeight"),s.style.lineHeight="",e.fn.autosize=function(i){return i=e.extend({},o,i||{}),s.parentNode!==document.body&&e(document.body).append(s),this.each(function(){function o(){var o,a={};if(t=d,s.className=i.className,r=parseInt(c.css("maxHeight"),10),e.each(n,function(e,t){a[t]=c.css(t)}),e(s).css(a),"oninput"in d){var l=d.style.width;d.style.width="0px",o=d.offsetWidth,d.style.width=l}}function a(){var n,a,p,f;t!==d&&o(),s.value=d.value+i.append,s.style.overflowY=d.style.overflowY,a=parseInt(d.style.height,10),"getComputedStyle"in window?(f=window.getComputedStyle(d),p=d.getBoundingClientRect().width,e.each(["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"],function(e,t){p-=parseInt(f[t],10)}),s.style.width=p+"px"):s.style.width=Math.max(c.width(),0)+"px",s.scrollTop=0,s.scrollTop=9e4,n=s.scrollTop,r&&n>r?(d.style.overflowY="scroll",n=r):(d.style.overflowY="hidden",l>n&&(n=l)),n+=h,a!==n&&(d.style.height=n+"px",u&&i.callback.call(d,d))}var r,l,d=this,c=e(d),h=0,u=e.isFunction(i.callback),p={height:d.style.height,overflow:d.style.overflow,overflowY:d.style.overflowY,wordWrap:d.style.wordWrap,resize:d.style.resize};if(!c.data("autosize")){if(c.data("autosize",!0),("border-box"===c.css("box-sizing")||"border-box"===c.css("-moz-box-sizing")||"border-box"===c.css("-webkit-box-sizing"))&&(h=c.outerHeight()-c.height()),l=Math.max(parseInt(c.css("minHeight"),10)-h||0,c.height()),c.css({overflow:"hidden",overflowY:"hidden",wordWrap:"break-word",resize:"none"===c.css("resize")||"vertical"===c.css("resize")?"none":"horizontal"}),"onpropertychange"in d?"oninput"in d?c.on("input.autosize keyup.autosize",a):c.on("propertychange.autosize",function(){"value"===event.propertyName&&a()}):c.on("input.autosize",a),i.resizeDelay!==!1){var f,w=e(d).width();e(window).on("resize.autosize",function(){clearTimeout(f),f=setTimeout(function(){e(d).width()!==w&&a()},parseInt(i.resizeDelay,10))})}c.on("autosize",a),c.on("autosize.includeStyle",function(){t=null,a()}),c.on("autosize.destroy",function(){t=null,c.off("autosize").off(".autosize").css(p).removeData("autosize")}),a()}})}})(window.jQuery||window.Zepto);
--------------------------------------------------------------------------------
/lib/ace/src-min/theme-textmate.js:
--------------------------------------------------------------------------------
1 | define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!1,b.cssClass="ace-tm",b.cssText=".ace-tm .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tm .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tm .ace_gutter { background: #e8e8e8; color: #333;}.ace-tm .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tm .ace_fold { background-color: #6B72E6;}.ace-tm .ace_text-layer { cursor: text;}.ace-tm .ace_cursor { border-left: 2px solid black;}.ace-tm .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid black;} .ace-tm .ace_line .ace_invisible { color: rgb(191, 191, 191);}.ace-tm .ace_line .ace_storage,.ace-tm .ace_line .ace_keyword { color: blue;}.ace-tm .ace_line .ace_constant { color: rgb(197, 6, 11);}.ace-tm .ace_line .ace_constant.ace_buildin { color: rgb(88, 72, 246);}.ace-tm .ace_line .ace_constant.ace_language { color: rgb(88, 92, 246);}.ace-tm .ace_line .ace_constant.ace_library { color: rgb(6, 150, 14);}.ace-tm .ace_line .ace_invalid { background-color: rgba(255, 0, 0, 0.1); color: red;}.ace-tm .ace_line .ace_support.ace_function { color: rgb(60, 76, 114);}.ace-tm .ace_line .ace_support.ace_constant { color: rgb(6, 150, 14);}.ace-tm .ace_line .ace_support.ace_type,.ace-tm .ace_line .ace_support.ace_class { color: rgb(109, 121, 222);}.ace-tm .ace_line .ace_keyword.ace_operator { color: rgb(104, 118, 135);}.ace-tm .ace_line .ace_string { color: rgb(3, 106, 7);}.ace-tm .ace_line .ace_comment { color: rgb(76, 136, 107);}.ace-tm .ace_line .ace_comment.ace_doc { color: rgb(0, 102, 255);}.ace-tm .ace_line .ace_comment.ace_doc.ace_tag { color: rgb(128, 159, 191);}.ace-tm .ace_line .ace_constant.ace_numeric { color: rgb(0, 0, 205);}.ace-tm .ace_line .ace_variable { color: rgb(49, 132, 149);}.ace-tm .ace_line .ace_xml_pe { color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function { color: #0000A2;}.ace-tm .ace_markup.ace_markupine { text-decoration:underline;}.ace-tm .ace_markup.ace_heading { color: rgb(12, 7, 255);}.ace-tm .ace_markup.ace_list { color:rgb(185, 6, 144);}.ace-tm .ace_marker-layer .ace_selection { background: rgb(181, 213, 255);}.ace-tm.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px white; border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step { background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack { background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active_line { background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter_active_line{ background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected_word { background: rgb(250, 250, 255); border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_meta.ace_tag { color:rgb(0, 50, 198);}.ace-tm .ace_string.ace_regex { color: rgb(255, 0, 0)}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)})
--------------------------------------------------------------------------------
/lib/json2.js:
--------------------------------------------------------------------------------
1 | var JSON;if(!JSON){JSON={}}(function(){function f(a){return a<10?"0"+a:a}function quote(a){escapable.lastIndex=0;return escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b==="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];if(i&&typeof i==="object"&&typeof i.toJSON==="function"){i=i.toJSON(a)}if(typeof rep==="function"){i=rep.call(b,a,i)}switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i){return"null"}gap+=indent;h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;cAdd Element").data('xml', {
46 | target : xmlElement,
47 | nodeType : "element"
48 | }).appendTo(this.menuContent);
49 | }
50 |
51 | if (xmlElement.allowAttributes) {
52 | $("Add Attribute").data('xml', {
53 | target : xmlElement,
54 | nodeType : "attribute"
55 | }).appendTo(this.menuContent);
56 | }
57 |
58 | $("Add CDATA").data('xml', {
59 | target : xmlElement,
60 | nodeType : "cdata"
61 | }).appendTo(this.menuContent);
62 |
63 | $("Add comment").data('xml', {
64 | target : xmlElement,
65 | nodeType : "comment"
66 | }).appendTo(this.menuContent);
67 |
68 | if (xmlElement.objectType.type != null && xmlElement.allowText) {
69 | this.addButton = $("Add text").attr({
70 | title : 'Add text'
71 | }).data('xml', {
72 | target : xmlElement,
73 | nodeType : "text"
74 | }).appendTo(this.menuContent);
75 | }
76 |
77 | if (this.expanded) {
78 | var endingHeight = this.menuContent.outerHeight();
79 | if (endingHeight == 0)
80 | endingHeight = 1;
81 | this.menuContent.css({height: startingHeight + "px"}).stop().animate({height: endingHeight + "px"}, menuExpandDuration).show();
82 | }
83 |
84 | if (this.menuContent.children().length == 0) {
85 | this.menuHeader.addClass("disabled");
86 | this.enabled = false;
87 | } else {
88 | this.menuHeader.removeClass("disabled");
89 | this.enabled = true;
90 | }
91 |
92 | return this;
93 | };
94 |
95 | AddNodeMenu.prototype.clear = function() {
96 | this.menuContent.hide();
97 | };
--------------------------------------------------------------------------------
/src/undo_history.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Manages the history of changes that have occurred, to allow progression forward
3 | * or backward through a limited history of modifications to the xml document
4 | * Current implementation involves storing previous states of the XML document,
5 | * recorded each time a significant change occurs or the document is regenerated
6 | */
7 | function UndoHistory(xmlState, editor) {
8 | this.xmlState = xmlState;
9 | this.editor = editor;
10 | // History of document states
11 | this.states = [];
12 | // Index of the currently active history state
13 | this.headIndex = -1;
14 | // Callback triggered after a change is undone or redone
15 | this.stateChangeEvent = null;
16 | // Callback triggered after a new state is added to the history
17 | this.stateCaptureEvent = null;
18 | // Disable undo history if the browser doesn't support cloning documents
19 | this.disabled = (typeof(document.implementation.createDocument) == "undefined");
20 | }
21 |
22 | UndoHistory.prototype.setStateChangeEvent = function(event) {
23 | this.stateChangeEvent = event;
24 | return this;
25 | };
26 |
27 | UndoHistory.prototype.setStateCaptureEvent = function(event) {
28 | this.stateCaptureEvent = event;
29 | return this;
30 | };
31 |
32 | // Clones an XML document and returns the new document
33 | UndoHistory.prototype.cloneNewDocument = function(originalDoc) {
34 | if (this.disabled) return;
35 | var newDoc = originalDoc.implementation.createDocument(
36 | originalDoc.namespaceURI, null, null
37 | );
38 | var newNode = newDoc.importNode(originalDoc.documentElement, true);
39 | newDoc.appendChild(newNode);
40 | return $(newDoc);
41 | };
42 |
43 | // Move the current active document to a different version from the history.
44 | // The step parameter indicates how many versions to move, and determines the direction to
45 | // move as well, where a negative number will undo changes, and a positive will redo.
46 | UndoHistory.prototype.changeHead = function(step){
47 | if (this.disabled) return;
48 | if ((step < 0 && this.headIndex + step < 0)
49 | || (step > 0 && this.headIndex + step >= this.states.length
50 | || this.headIndex + step >= this.editor.options.undoHistorySize))
51 | return;
52 |
53 | this.headIndex += step;
54 | // Clone the newly selected document head, otherwise this state would be lost from
55 | // the history when any new changes were made
56 | this.xmlState.xml = this.cloneNewDocument(this.states[this.headIndex][0]);
57 |
58 | if (this.stateChangeEvent != null)
59 | this.stateChangeEvent(this);
60 | };
61 |
62 | // Capture the current state of the XML document into the document history
63 | UndoHistory.prototype.captureSnapshot = function () {
64 | if (this.disabled) return;
65 | if (this.editor.options.undoHistorySize <= 0)
66 | return;
67 |
68 | if (this.headIndex < this.states.length - 1) {
69 | this.states = this.states.slice(0, this.headIndex + 1);
70 | }
71 |
72 | if (this.states.length >= this.editor.options.undoHistorySize) {
73 | this.states = this.states.slice(1, this.states.length);
74 | }
75 |
76 | this.headIndex = this.states.length;
77 |
78 | this.states.push(this.cloneNewDocument(this.xmlState.xml[0]));
79 |
80 | if (this.stateCaptureEvent != null)
81 | this.stateCaptureEvent(this);
82 | };
83 |
--------------------------------------------------------------------------------
/demo/examples/eac-cpf/xlink.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/tests/issue-084-cpf/xlink.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/demo/examples/mods-3-4/xlink.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/tests/issue-078-mods-3-4/xlink.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/src/xml_text_node.js:
--------------------------------------------------------------------------------
1 | function XMLTextNode(textNode, dataType, editor, vocabulary) {
2 | var textType = {
3 | text : true,
4 | type : dataType
5 | };
6 |
7 | this.textNode = textNode;
8 | this.xmlNode = $(textNode);
9 | this.vocabulary = vocabulary;
10 |
11 | AbstractXMLObject.call(this, textType, editor);
12 |
13 | }
14 |
15 | XMLTextNode.prototype.constructor = XMLTextNode;
16 | XMLTextNode.prototype = Object.create( AbstractXMLObject.prototype );
17 |
18 | // Persist the input value back into the text node
19 | XMLTextNode.prototype.syncText = function() {
20 | this.textNode.nodeValue = this.textInput.val();
21 | };
22 |
23 | XMLTextNode.prototype.select = function() {
24 | $(".selected").removeClass("selected");
25 | this.domNode.closest("." + xmlElementClass).addClass("selected");
26 | this.domNode.addClass("selected");
27 |
28 | };
29 |
30 | XMLTextNode.prototype.addXmlNode = function(prepend) {
31 | var textValue = "";
32 | if (!this.textNode) {
33 | this.textNode = document.createTextNode("");
34 | if (prepend) {
35 | this.parentElement.xmlNode.prepend(this.textNode);
36 | } else {
37 | this.parentElement.xmlNode[0].appendChild(this.textNode);
38 | }
39 | this.xmlNode = $(this.textNode);
40 | } else {
41 | textValue = this.textNode.nodeValue;
42 | }
43 | return textValue;
44 | };
45 |
46 | XMLTextNode.prototype.render = function(parentElement, prepend) {
47 | this.parentElement = parentElement;
48 | this.domNodeID = this.guiEditor.nextIndex();
49 |
50 | // Create the element and add it to the container
51 | this.domNode = document.createElement('div');
52 | var $domNode = $(this.domNode);
53 | this.domNode.id = this.domNodeID;
54 | this.domNode.className = xmlNodeClass + ' ' + xmlTextClass;
55 |
56 | if (prepend) {
57 | this.parentElement.nodeContainer.prepend(this.domNode);
58 | } else {
59 | this.parentElement.nodeContainer[0].appendChild(this.domNode);
60 | }
61 |
62 | var inputColumn = document.createElement('div');
63 | inputColumn.className = 'xml_input_column';
64 | this.domNode.appendChild(inputColumn);
65 |
66 | var textValue = this.addXmlNode(prepend);
67 |
68 | this.textInput = AbstractXMLObject.prototype.createElementInput.call(this,
69 | this.domNodeID + "_text", textValue, inputColumn);
70 | this.textInput.addClass('element_text');
71 | if (this.vocabulary && this.vocabulary.values) {
72 | this.textInput.autocomplete({
73 | source : this.vocabulary.values
74 | });
75 | }
76 |
77 | this.deleteButton = document.createElement('div');
78 | this.deleteButton.className = 'xml_delete';
79 | this.deleteButton.appendChild(document.createTextNode('x'));
80 | this.domNode.appendChild(this.deleteButton);
81 |
82 | this.domNode = $domNode;
83 | this.domNode.data("xmlObject", this);
84 |
85 | return this.domNode;
86 | };
87 |
88 | XMLTextNode.prototype.swap = function(swapTarget) {
89 | AbstractXMLObject.prototype.swap.call(this, swapTarget);
90 | };
91 |
92 | XMLTextNode.prototype.moveUp = function() {
93 | AbstractXMLObject.prototype.moveUp.call(this);
94 | };
95 |
96 | XMLTextNode.prototype.moveDown = function() {
97 | AbstractXMLObject.prototype.moveDown.call(this);
98 | };
99 |
100 | XMLTextNode.prototype.focus = function() {
101 | AbstractXMLObject.prototype.focus.call(this);
102 | };
103 |
104 | XMLTextNode.prototype.isSelected = function() {
105 | return AbstractXMLObject.prototype.isSelected.call(this);
106 | };
--------------------------------------------------------------------------------
/src/xml_attribute.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Stores data representing a single attribute for an element
3 | */
4 | function XMLAttribute(objectType, xmlElement, editor) {
5 | AbstractXMLObject.call(this, objectType, editor);
6 | // the XMLElement object which this attribute belongs to.
7 | this.xmlElement = xmlElement;
8 |
9 | this.attributeInput = null;
10 | // The menu button associated with this attribute. Used for reenabling attribute in menu on remove
11 | // TODO replace this with a more general solution
12 | this.addButton = null;
13 |
14 | var prefix;
15 | this.attributeName = objectType.localName;
16 | // Determine whether the attribute name should include a namespace prefix
17 | if (this.xmlElement.objectType.namespace != this.objectType.namespace) {
18 | prefix = this.editor.xmlState.getNamespacePrefix(this.objectType.namespace);
19 | this.attributeName = prefix + this.attributeName;
20 | }
21 | }
22 |
23 | XMLAttribute.prototype.constructor = XMLAttribute;
24 | XMLAttribute.prototype = Object.create( AbstractXMLObject.prototype );
25 |
26 | // Render the gui representation of this attribute
27 | XMLAttribute.prototype.render = function (){
28 | if (!this.xmlElement.domNode)
29 | return;
30 |
31 | this.domNodeID = this.xmlElement.domNodeID + "_" + this.objectType.ns + "_" + this.objectType.localName;
32 |
33 | this.domNode = $("").attr({
34 | 'id' : this.domNodeID + "_cont",
35 | 'class' : attributeContainerClass
36 | }).data('xmlAttribute', this).appendTo(this.xmlElement.getAttributeContainer());
37 |
38 | var self = this;
39 | var removeButton = document.createElement('a');
40 | removeButton.appendChild(document.createTextNode('(x) '));
41 | this.domNode[0].appendChild(removeButton);
42 |
43 | var label = document.createElement('label');
44 | var prefix = this.editor.xmlState.namespaces.getNamespacePrefix(this.objectType.namespace);
45 | label.appendChild(document.createTextNode(prefix + this.objectType.localName));
46 | this.domNode[0].appendChild(label);
47 |
48 | var attributeValue = this.xmlElement.xmlNode.attr(this.attributeName);
49 | if (attributeValue == '' && this.objectType.defaultValue != null) {
50 | attributeValue = this.objectType.defaultValue;
51 | }
52 |
53 | this.attributeInput = this.createElementInput(this.domNodeID.replace(":", "-"), attributeValue, this.domNode[0]);
54 | this.attributeInput.data('xmlAttribute', this);
55 |
56 | return this.attributeInput;
57 | };
58 |
59 | XMLAttribute.prototype.remove = function() {
60 | // Tell the button associated with this attribute that it was removed. Replace this
61 | if ($("#" + this.domNodeID).length > 0) {
62 | if (this.addButton != null){
63 | this.addButton.removeClass("disabled");
64 | }
65 | }
66 | this.xmlElement.removeAttribute(this.objectType);
67 | this.domNode.remove();
68 | };
69 |
70 | // Synchronize this attributes value from the gui input back to the xml document
71 | XMLAttribute.prototype.syncValue = function() {
72 | this.xmlElement.xmlNode.attr(this.attributeName, this.attributeInput.val());
73 | };
74 |
75 | // Change the attribute's value in the xml document to value
76 | XMLAttribute.prototype.changeValue = function(value) {
77 | this.xmlElement.xmlNode.attr(this.attributeName, value);
78 | };
79 |
80 | XMLAttribute.prototype.select = function() {
81 | this.editor.guiEditor.selectNode(this.xmlElement);
82 | this.domNode.addClass("selected");
83 | this.attributeInput.focus();
84 | };
85 |
86 | XMLAttribute.prototype.deselect = function() {
87 | this.domNode.removeClass('selected');
88 | };
89 |
--------------------------------------------------------------------------------
/xsd/src/xsd2json.js:
--------------------------------------------------------------------------------
1 | //= require_self
2 | //= require_tree .
3 | /*
4 |
5 | Copyright 2008 The University of North Carolina at Chapel Hill
6 |
7 | Licensed under the Apache License, Version 2.0 (the "License");
8 | you may not use this file except in compliance with the License.
9 | You may obtain a copy of the License atthis
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing, software
14 | distributed under the License is distributed on an "AS IS" BASIS,
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | See the License for the specific language governing permissions and
17 | limitations under the License.
18 |
19 | */
20 | /*
21 | * Converts xml schemas to usable json objects, focused on elements and attributes. Result is a javascript
22 | * object representing a starting node from the base schema, with recursive relations to all its children
23 | * and attributes. The resulting structure can then be used or exported.
24 | *
25 | * Intended for populating forms rather than validation. Not all restrictions are extracted at this time.
26 | *
27 | * Due to cross browser domain restrictions on ajax calls, the schema and its imports must all
28 | * be stored within the same domain as this script.
29 | *
30 | * @author Ben Pennell
31 | */
32 | function Xsd2Json(originatingXsdName, options) {
33 | var defaults = {
34 | schemaURI: ""
35 | };
36 | this.options = $.extend({}, defaults, options);
37 |
38 | this.xsdManager = new SchemaManager(originatingXsdName, options);
39 |
40 | };
41 |
42 | Xsd2Json.prototype.getSchema = function() {
43 | var self = this;
44 | return function() {
45 | return self.xsdManager.originatingRoot;
46 | };
47 | };
48 |
49 | /**
50 | * Converts the computed schema object into JSON and returns as a string. If pretty is
51 | * true, then the json will use pretty formatting.
52 | * @param pretty
53 | * @returns
54 | */
55 | Xsd2Json.prototype.stringify = function(pretty) {
56 | if (this.xsdManager.originatingRoot == null)
57 | throw new Error("Root element was not set, cannot convert to JSON.");
58 | if (pretty) {
59 | return vkbeautify.json(JSON.stringify(JSON.decycle(this.xsdManager.originatingRoot)));
60 | }
61 | return JSON.stringify(JSON.decycle(this.xsdManager.originatingRoot));
62 | };
63 |
64 | /**
65 | * Creates a file named from the computed schema object, converted to JSON.
66 | * If variableName is provided, then the JSON will be output so that it is assigned to a variable of
67 | * the same name in the exported JSON file. Allows for caching to a file without needing to use eval to reload.
68 | * If pretty is provided, the json will use pretty formatting.
69 | * @param filename
70 | * @param variableName
71 | * @param pretty
72 | * @returns {Boolean}
73 | */
74 | Xsd2Json.prototype.exportJSON = function(filename, variableName, pretty) {
75 | // JSON versus JS
76 | window.URL = window.webkitURL || window.URL;
77 | window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
78 |
79 | if (window.BlobBuilder === undefined) {
80 | alert("Browser does not support saving files.");
81 | return false;
82 | }
83 |
84 | var jsonString = this.stringify(pretty);
85 | if (variableName != null){
86 | jsonString = "var " + variableName + " = " + jsonString + ";";
87 | }
88 | var blobBuilder = new BlobBuilder();
89 | blobBuilder.append(jsonString);
90 |
91 | var mimeType = "application/json";
92 |
93 | var a = document.createElement('a');
94 | a.download = filename;
95 | a.href = window.URL.createObjectURL(blobBuilder.getBlob(mimeType));
96 |
97 | a.dataset.downloadurl = [mimeType, a.download, a.href].join(':');
98 | a.target = "exportJSON";
99 |
100 | var event = document.createEvent("MouseEvents");
101 | event.initMouseEvent(
102 | "click", true, false, window, 0, 0, 0, 0, 0
103 | , false, false, false, false, 0, null
104 | );
105 | a.dispatchEvent(event);
106 | };
--------------------------------------------------------------------------------
/src/xml_unspecified_element.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Stores data related to a single xml element as it is represented in both the base XML
3 | * document and GUI
4 | */
5 | function XMLUnspecifiedElement(xmlNode, editor) {
6 | var unspecifiedType = {
7 | element : true,
8 | type : "mixed"
9 | };
10 |
11 | AbstractXMLObject.call(this, unspecifiedType, editor);
12 | // jquery object reference to the xml node represented by this object in the active xml document
13 | this.xmlNode = $(xmlNode);
14 | this.isRootElement = this.xmlNode[0].parentNode === this.xmlNode[0].ownerDocument;
15 | // Flag indicating if this element is a child of the root node
16 | this.isTopLevel = this.xmlNode[0].parentNode.parentNode === this.xmlNode[0].ownerDocument;
17 | this.allowChildren = true;
18 | // Flag indicating if any attributes can be added to this element
19 | this.allowAttributes = true;
20 | // Should this element allow text nodes to be added
21 | this.allowText = true;
22 | // dom element header for this element
23 | this.elementHeader = null;
24 | // dom element which contains the display of child nodes
25 | this.nodeContainer = null;
26 |
27 | this.tagName = "";
28 | }
29 |
30 | XMLUnspecifiedElement.prototype.constructor = XMLUnspecifiedElement;
31 | XMLUnspecifiedElement.prototype = Object.create( XMLElement.prototype );
32 |
33 | XMLUnspecifiedElement.prototype.render = function(parentElement, recursive, relativeTo, prepend) {
34 | this.parentElement = parentElement;
35 | this.domNodeID = this.guiEditor.nextIndex();
36 |
37 | // Create the element and add it to the container
38 | this.domElement = document.createElement('div');
39 | this.domNode = $(this.domElement);
40 |
41 | this.domElement.id = this.domNodeID;
42 | this.domElement.className = 'xml_node ' + xmlElementClass;
43 | if (this.isTopLevel)
44 | this.domElement.className += ' ' + topLevelContainerClass;
45 | if (this.isRootElement)
46 | this.domElement.className += ' xml_root_element';
47 |
48 | this.insertDOMNode(relativeTo, prepend);
49 |
50 | // Begin building contents
51 | this.elementHeader = document.createElement('ul');
52 | this.elementHeader.className = 'element_header';
53 | this.domElement.appendChild(this.elementHeader);
54 | var elementNameContainer = document.createElement('li');
55 | elementNameContainer.className = 'element_name';
56 | this.elementHeader.appendChild(elementNameContainer);
57 |
58 | this.elementName = this.xmlNode[0].tagName;
59 |
60 | // set up element title and entry field if appropriate
61 | var titleElement = document.createElement('span');
62 | titleElement.appendChild(document.createTextNode(this.elementName));
63 | elementNameContainer.appendChild(titleElement);
64 |
65 | // Switch gui element over to a jquery object
66 | this.domNode.data("xmlObject", this);
67 |
68 | // Add the subsections for the elements content next.
69 | this.addContentContainers(recursive);
70 |
71 | // Action buttons
72 | if (!this.isRootElement)
73 | this.elementHeader.appendChild(this.addTopActions(this.domNodeID));
74 |
75 | this.initializeGUI();
76 | this.updated({action : 'render'});
77 |
78 | return this.domNode;
79 | };
80 |
81 | XMLUnspecifiedElement.prototype.addContentContainers = function (recursive) {
82 | var attributesArray = this.objectType.attributes;
83 | var elementsArray = this.objectType.elements;
84 |
85 | this.contentContainer = document.createElement("div");
86 | this.domElement.appendChild(this.contentContainer);
87 |
88 | var placeholder = document.createElement('div');
89 | placeholder.className = 'placeholder';
90 |
91 | placeholder.appendChild(document.createTextNode('Use the menu to add contents.'));
92 |
93 | this.contentContainer.appendChild(placeholder);
94 | this.placeholder = $(placeholder);
95 |
96 | this.addAttributeContainer();
97 |
98 | this.addNodeContainer(recursive);
99 | };
100 |
101 | XMLUnspecifiedElement.prototype.updateChildrenCount = function(childElement, delta) {
102 | this.nodeCount += delta;
103 | };
104 |
105 | XMLUnspecifiedElement.prototype.childCanBeRemoved = function(childType) {
106 | return true;
107 | };
--------------------------------------------------------------------------------
/demo/examples/marc_relators.json:
--------------------------------------------------------------------------------
1 | [ "Abridger", "Art copyist", "Actor", "Art director", "Adapter", "Author of afterword, colophon, etc.", "Analyst", "Animator", "Annotator", "Bibliographic antecedent", "Appellee", "Appellant", "Applicant", "Author in quotations or text abstracts", "Architect", "Artistic director", "Arranger", "Artist", "Assignee", "Associated name", "Autographer", "Attributed name", "Auctioneer", "Author of dialog", "Author of introduction, etc.", "Screenwriter", "Author", "Binding designer", "Bookjacket designer", "Book designer", "Book producer", "Blurb writer", "Binder", "Bookplate designer", "Broadcaster", "Braille embosser", "Bookseller", "Caster", "Conceptor", "Choreographer", "Client", "Calligrapher", "Colorist", "Collotyper", "Commentator", "Composer", "Compositor", "Conductor", "Cinematographer", "Censor", "Contestant-appellee", "Collector", "Compiler", "Conservator", "Collection registrar", "Contestant", "Contestant-appellant", "Court governed", "Cover designer", "Copyright claimant", "Complainant-appellee", "Copyright holder", "Complainant", "Complainant-appellant", "Creator", "Correspondent", "Corrector", "Court reporter", "Consultant", "Consultant to a project", "Costume designer", "Contributor", "Contestee-appellee", "Cartographer", "Contractor", "Contestee", "Contestee-appellant", "Curator", "Commentator for written text", "Distribution place", "Defendant", "Defendant-appellee", "Defendant-appellant", "Degree granting institution", "Degree supervisor", "Dissertant", "Delineator", "Dancer", "Donor", "Depicted", "Depositor", "Draftsman", "Director", "Designer", "Distributor", "Data contributor", "Dedicatee", "Data manager", "Dedicator", "Dubious author", "Editor of compilation", "Editor of moving image work", "Editor", "Engraver", "Electrician", "Electrotyper", "Engineer", "Enacting jurisdiction", "Etcher", "Event place", "Expert", "Facsimilist", "Film distributor", "Field director", "Film editor", "Film director", "Filmmaker", "Former owner", "Film producer", "Funder", "First party", "Forger", "Geographic information specialist", "Host institution", "Honoree", "Host", "Illustrator", "Illuminator", "Inscriber", "Inventor", "Issuing body", "Instrumentalist", "Interviewee", "Interviewer", "Judge", "Jurisdiction governed", "Laboratory", "Librettist", "Laboratory director", "Lead", "Libelee-appellee", "Libelee", "Lender", "Libelee-appellant", "Lighting designer", "Libelant-appellee", "Libelant", "Libelant-appellant", "Landscape architect", "Licensee", "Licensor", "Lithographer", "Lyricist", "Music copyist", "Metadata contact", "Medium", "Manufacture place", "Manufacturer", "Moderator", "Monitor", "Marbler", "Markup editor", "Musical director", "Metal-engraver", "Minute taker", "Musician", "Narrator", "Opponent", "Originator", "Organizer", "Onscreen presenter", "Other", "Owner", "Panelist", "Patron", "Publishing director", "Publisher", "Project director", "Proofreader", "Photographer", "Platemaker", "Permitting agency", "Production manager", "Printer of plates", "Papermaker", "Puppeteer", "Praeses", "Process contact", "Production personnel", "Presenter", "Performer", "Programmer", "Printmaker", "Production company", "Producer", "Production place", "Production designer", "Printer", "Provider", "Patent applicant", "Plaintiff-appellee", "Plaintiff", "Patent holder", "Plaintiff-appellant", "Publication place", "Rubricator", "Recordist", "Recording engineer", "Addressee", "Radio director", "Redaktor", "Renderer", "Researcher", "Reviewer", "Radio producer", "Repository", "Reporter", "Responsible party", "Respondent-appellee", "Restager", "Respondent", "Restorationist", "Respondent-appellant", "Research team head", "Research team member", "Scientific advisor", "Scenarist", "Sculptor", "Scribe", "Sound designer", "Secretary", "Stage director", "Signer", "Supporting host", "Seller", "Singer", "Speaker", "Sponsor", "Second party", "Surveyor", "Set designer", "Setting", "Storyteller", "Stage manager", "Standards body", "Stereotyper", "Technical director", "Teacher", "Thesis advisor", "Television director", "Television producer", "Transcriber", "Translator", "Type designer", "Typographer", "University place", "Voice actor", "Videographer", "Writer of added commentary", "Writer of added lyrics", "Writer of accompanying material", "Writer of added text", "Woodcutter", "Wood engraver", "Writer of introduction", "Witness", "Writer of preface", "Writer of supplementary textual content" ]
--------------------------------------------------------------------------------
/demo/examples/dcterms/dc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMES 1.1 XML Schema
11 | XML Schema for http://purl.org/dc/elements/1.1/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema declares XML elements for the 15 DC elements from the
24 | http://purl.org/dc/elements/1.1/ namespace.
25 |
26 | It defines a complexType SimpleLiteral which permits mixed content
27 | and makes the xml:lang attribute available. It disallows child elements by
28 | use of minOcccurs/maxOccurs.
29 |
30 | However, this complexType does permit the derivation of other complexTypes
31 | which would permit child elements.
32 |
33 | All elements are declared as substitutable for the abstract element any,
34 | which means that the default type for all elements is dc:SimpleLiteral.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 | This is the default type for all of the DC elements.
49 | It permits text content only with optional
50 | xml:lang attribute.
51 | Text is allowed because mixed="true", but sub-elements
52 | are disallowed because minOccurs="0" and maxOccurs="0"
53 | are on the xs:any tag.
54 |
55 | This complexType allows for restriction or extension permitting
56 | child elements.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | This group is included as a convenience for schema authors
92 | who need to refer to all the elements in the
93 | http://purl.org/dc/elements/1.1/ namespace.
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | This complexType is included as a convenience for schema authors who need to define a root
108 | or container element for all of the DC elements.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/demo/examples/test/dc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMES 1.1 XML Schema
11 | XML Schema for http://purl.org/dc/elements/1.1/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema declares XML elements for the 15 DC elements from the
24 | http://purl.org/dc/elements/1.1/ namespace.
25 |
26 | It defines a complexType SimpleLiteral which permits mixed content
27 | and makes the xml:lang attribute available. It disallows child elements by
28 | use of minOcccurs/maxOccurs.
29 |
30 | However, this complexType does permit the derivation of other complexTypes
31 | which would permit child elements.
32 |
33 | All elements are declared as substitutable for the abstract element any,
34 | which means that the default type for all elements is dc:SimpleLiteral.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 | This is the default type for all of the DC elements.
49 | It permits text content only with optional
50 | xml:lang attribute.
51 | Text is allowed because mixed="true", but sub-elements
52 | are disallowed because minOccurs="0" and maxOccurs="0"
53 | are on the xs:any tag.
54 |
55 | This complexType allows for restriction or extension permitting
56 | child elements.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | This group is included as a convenience for schema authors
92 | who need to refer to all the elements in the
93 | http://purl.org/dc/elements/1.1/ namespace.
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | This complexType is included as a convenience for schema authors who need to define a root
108 | or container element for all of the DC elements.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/tests/issue-078-dcterms/dc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMES 1.1 XML Schema
11 | XML Schema for http://purl.org/dc/elements/1.1/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema declares XML elements for the 15 DC elements from the
24 | http://purl.org/dc/elements/1.1/ namespace.
25 |
26 | It defines a complexType SimpleLiteral which permits mixed content
27 | and makes the xml:lang attribute available. It disallows child elements by
28 | use of minOcccurs/maxOccurs.
29 |
30 | However, this complexType does permit the derivation of other complexTypes
31 | which would permit child elements.
32 |
33 | All elements are declared as substitutable for the abstract element any,
34 | which means that the default type for all elements is dc:SimpleLiteral.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 | This is the default type for all of the DC elements.
49 | It permits text content only with optional
50 | xml:lang attribute.
51 | Text is allowed because mixed="true", but sub-elements
52 | are disallowed because minOccurs="0" and maxOccurs="0"
53 | are on the xs:any tag.
54 |
55 | This complexType allows for restriction or extension permitting
56 | child elements.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | This group is included as a convenience for schema authors
92 | who need to refer to all the elements in the
93 | http://purl.org/dc/elements/1.1/ namespace.
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | This complexType is included as a convenience for schema authors who need to define a root
108 | or container element for all of the DC elements.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/tests/issue-080-include-test/dc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMES 1.1 XML Schema
11 | XML Schema for http://purl.org/dc/elements/1.1/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema declares XML elements for the 15 DC elements from the
24 | http://purl.org/dc/elements/1.1/ namespace.
25 |
26 | It defines a complexType SimpleLiteral which permits mixed content
27 | and makes the xml:lang attribute available. It disallows child elements by
28 | use of minOcccurs/maxOccurs.
29 |
30 | However, this complexType does permit the derivation of other complexTypes
31 | which would permit child elements.
32 |
33 | All elements are declared as substitutable for the abstract element any,
34 | which means that the default type for all elements is dc:SimpleLiteral.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 | This is the default type for all of the DC elements.
49 | It permits text content only with optional
50 | xml:lang attribute.
51 | Text is allowed because mixed="true", but sub-elements
52 | are disallowed because minOccurs="0" and maxOccurs="0"
53 | are on the xs:any tag.
54 |
55 | This complexType allows for restriction or extension permitting
56 | child elements.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | This group is included as a convenience for schema authors
92 | who need to refer to all the elements in the
93 | http://purl.org/dc/elements/1.1/ namespace.
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | This complexType is included as a convenience for schema authors who need to define a root
108 | or container element for all of the DC elements.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/tests/issue-080-no-target-ns/dc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | DCMES 1.1 XML Schema
11 | XML Schema for http://purl.org/dc/elements/1.1/ namespace
12 |
13 | Created 2008-02-11
14 |
15 | Created by
16 |
17 | Tim Cole (t-cole3@uiuc.edu)
18 | Tom Habing (thabing@uiuc.edu)
19 | Jane Hunter (jane@dstc.edu.au)
20 | Pete Johnston (p.johnston@ukoln.ac.uk),
21 | Carl Lagoze (lagoze@cs.cornell.edu)
22 |
23 | This schema declares XML elements for the 15 DC elements from the
24 | http://purl.org/dc/elements/1.1/ namespace.
25 |
26 | It defines a complexType SimpleLiteral which permits mixed content
27 | and makes the xml:lang attribute available. It disallows child elements by
28 | use of minOcccurs/maxOccurs.
29 |
30 | However, this complexType does permit the derivation of other complexTypes
31 | which would permit child elements.
32 |
33 | All elements are declared as substitutable for the abstract element any,
34 | which means that the default type for all elements is dc:SimpleLiteral.
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
44 |
45 |
46 |
47 |
48 | This is the default type for all of the DC elements.
49 | It permits text content only with optional
50 | xml:lang attribute.
51 | Text is allowed because mixed="true", but sub-elements
52 | are disallowed because minOccurs="0" and maxOccurs="0"
53 | are on the xs:any tag.
54 |
55 | This complexType allows for restriction or extension permitting
56 | child elements.
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | This group is included as a convenience for schema authors
92 | who need to refer to all the elements in the
93 | http://purl.org/dc/elements/1.1/ namespace.
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | This complexType is included as a convenience for schema authors who need to define a root
108 | or container element for all of the DC elements.
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/schema_tree.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Unpacks the elements of the schema object into structures to accomodate lookup
3 | * of definitions by name and position within the schema hierarchy.
4 | */
5 | function SchemaTree(rootElement) {
6 | // Map of elements stored by name. If there are name collisions, then elements are stored in a list
7 | this.nameToDef = {};
8 | // Root of the schema tree
9 | this.rootElement = rootElement;
10 | // Store namespaces from the schema in a schema specific namespace list
11 | this.namespaceIndexes = this.rootElement.namespaces;
12 | this.namespaces = new NamespaceList();
13 | for (var index in this.namespaceIndexes) {
14 | var def = this.namespaceIndexes[index];
15 | this.namespaces.addNamespace(def.uri, def.prefix);
16 | }
17 | }
18 |
19 | // Recursively walk the provided schema to construct necessary representations of the tree for the editord
20 | SchemaTree.prototype.build = function(elementName, elementDef, parentDef) {
21 | // Default to the root element if no element is given.
22 | if (arguments.length == 0) {
23 | elementName = this.rootElement.ns + ":" + this.rootElement.name;
24 | elementDef = this.rootElement;
25 | parentDef = null;
26 | }
27 |
28 | // Store a reference from this instance of an element back to the current parent.
29 | // These are needed to assist in disambiguating when multiple definitions share a name in a namespace
30 | if ("parents" in elementDef) {
31 | // Definition already has a parent, so add parent reference and return to avoid loop
32 | elementDef.parents.push(parentDef);
33 | return;
34 | } else {
35 | elementDef["parents"] = [parentDef];
36 | }
37 |
38 | var namespaceDefinition = this.namespaceIndexes[elementDef.ns];
39 | //Resolve namespace index into actual namespace uri
40 | elementDef.namespace = namespaceDefinition.uri;
41 | // Split element name into localName and prefixed name
42 | if (!elementDef.schema) {
43 | elementDef.localName = elementDef.name;
44 | elementDef.name = (namespaceDefinition.prefix? namespaceDefinition.prefix + ":" : "") + elementDef.localName;
45 | }
46 |
47 | // Add this definition to the map of elements. If there is a name collision, store the
48 | // elements with overlapping names together in a list
49 | var definitionList = this.nameToDef[elementName];
50 | if (definitionList == null) {
51 | this.nameToDef[elementName] = [elementDef];
52 | } else {
53 | this.nameToDef[elementName].push(elementDef);
54 | }
55 |
56 | var self = this;
57 | // Expand namespaces and names of attributes available to this element
58 | if (elementDef.attributes)
59 | $.each(elementDef.attributes, function() {
60 | if (this.localName)
61 | return true;
62 | this.localName = this.name;
63 | var namespaceDefinition = self.namespaceIndexes[this.ns];
64 | this.namespace = namespaceDefinition.uri;
65 | this.name = (namespaceDefinition.prefix? namespaceDefinition.prefix + ":" : "") + this.localName;
66 | });
67 | // Call build on all the child elements of this element to continue the walk.
68 | $.each(elementDef.elements, function() {
69 | self.build(this.ns + ":" + this.name, this, elementDef);
70 | });
71 | };
72 |
73 | // Retrieves the schema definition the provided element node. If more than one definition is
74 | // found for the element by name and namespace, then attempts to disambiguate by parents
75 | SchemaTree.prototype.getElementDefinition = function(elementNode) {
76 | var namespaceIndex = 0;
77 | $.each(this.namespaceIndexes, function(){
78 | if (this.uri == elementNode.namespaceURI)
79 | return false;
80 | namespaceIndex++;
81 | });
82 | var prefixedName = namespaceIndex + ":" + localName(elementNode);
83 | var defList = this.nameToDef[prefixedName];
84 | if (defList == null)
85 | return null;
86 | if (defList.length == 1)
87 | return defList[0];
88 |
89 | for (index in defList) {
90 | if (this.pathMatches(elementNode, defList[index]))
91 | return defList[index];
92 | }
93 | };
94 |
95 | // Returns true if all the ancestors of the provided element match all the ancestors
96 | // defined for this element in the schema
97 | SchemaTree.prototype.pathMatches = function(elementNode, definition) {
98 | var isRootNode = elementNode.parentNode instanceof Document;
99 | var parentNode = elementNode.parentNode;
100 | for (index in definition.parents) {
101 | var parentDef = definition.parents[index];
102 | if (isRootNode) {
103 | // If this is a root node and the definition allows it, then we have a match
104 | if (definition.parents[index] == null || definition.parents[index].schema)
105 | return true;
106 | } else {
107 | if (parentDef.localName == localName(parentNode) && parentDef.namespace == parentNode.namespaceURI) {
108 | // Parent definitions matched, so continue the walk
109 | var answer = this.pathMatches(parentNode, parentDef);
110 | // If this particular parent definition matched all the way, then return true.
111 | if (answer)
112 | return true;
113 | }
114 | }
115 | }
116 | return false;
117 | };
--------------------------------------------------------------------------------
/src/xml_templates.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create class to focus, select and load default XML templates
3 | * @param init_object
4 | * @constructor
5 | */
6 | function XMLTemplates(init_object) {
7 | this.template_path = init_object.options.templateOptions.templatePath;
8 | this.templates = init_object.options.templateOptions.templates;
9 | this.editor = init_object;
10 | this.extension_regx = /\.\w{3,}$/;
11 | }
12 |
13 | XMLTemplates.prototype.constructor = XMLTemplates;
14 |
15 | XMLTemplates.prototype.createChooseTemplate = function() {
16 | this.templateForm();
17 | this.createDialog();
18 | this.loadEvents();
19 | };
20 |
21 | /**
22 | * Load the dialog form for user to select a template from a list of provided templates
23 | * @returns {*|jQuery}
24 | */
25 | XMLTemplates.prototype.createDialog = function() {
26 | var self = this;
27 | var buttons = {};
28 | if (self.editor.options.templateOptions.cancelFunction) {
29 | buttons["Cancel"] = $.proxy(self.editor.options.templateOptions.cancelFunction, self);
30 | }
31 | buttons["Choose"] = function() {
32 | self.processForm();
33 | };
34 |
35 | this.form.dialog({
36 | autoOpen: true,
37 | dialogClass: "jquery-editor-no-close template-form",
38 | height: 350,
39 | width: 500,
40 | modal: true,
41 | buttons: buttons
42 | });
43 | };
44 |
45 | /**
46 | * Create form & add to DOM
47 | * Don't think we can assume user will build this form themselves
48 | */
49 | XMLTemplates.prototype.templateForm = function() {
50 | var form = '';
81 |
82 | this.form = $(form);
83 | this.form.insertAfter("body");
84 | $('li:first', this.form).addClass('focus');
85 | };
86 |
87 | /**
88 | * Select a template from the form
89 | */
90 | XMLTemplates.prototype.processForm = function() {
91 | // Split on mdash if description present
92 | var selection = $(".focus a", this.form).attr('href');
93 |
94 | this.form.dialog("close");
95 | this.loadSelectedTemplate(selection);
96 | };
97 |
98 | /**
99 | * Load selected template.
100 | * @param selection
101 | */
102 | XMLTemplates.prototype.loadSelectedTemplate = function(selection) {
103 | var self = this;
104 | // Default template loading doesn't have access to xml_templates constructor
105 | $.ajax({
106 | url: this.template_path + selection,
107 | dataType: "xml"
108 | }).done(function(data) {
109 | var xml_string = self.editor.xml2Str(data);
110 | if (self.editor.xmlState !== null) {
111 | self.editor.xmlState = null; // Remove old state for garbage collection
112 | self.editor.xmlState = new DocumentState(xml_string, self.editor);
113 | self.editor.xmlState.extractNamespacePrefixes();
114 | self.editor.refreshDisplay();
115 | self.editor.activeEditor.selectRoot();
116 | } else {
117 | self.editor._documentReady(xml_string);
118 | }
119 | }).fail(function(jqXHR, textStatus) {
120 | alert("Unable to load the requested template: " + textStatus);
121 | });
122 | };
123 |
124 | /**
125 | * Highlight and focus currently selected template
126 | * If enter hit go ahead and load focused template
127 | */
128 | XMLTemplates.prototype.focusTemplate = function() {
129 | var self = this;
130 |
131 | // Focus selected template
132 | this.form.on('keydown click', '.templating', function(e) {
133 | var key = e.which;
134 | var number_of_forms, base_element, current, form_id, next_element;
135 |
136 | if (key === 1 || key === 9) {
137 | e.preventDefault();
138 | number_of_forms = $('.templating').length;
139 |
140 | // Left click, select the clicked target
141 | if (key == 1) {
142 | base_element = $(e.target);
143 | if (!base_element.hasClass("templating")) {
144 | base_element = base_element.parent(".templating");
145 | }
146 | } else {
147 | current = $('.focus', self.form).attr('id');
148 | form_id = parseInt(current.slice(-1)) + 1;
149 | next_element = (form_id === number_of_forms) ? 0 : form_id;
150 | base_element = $('#template_' + next_element);
151 | }
152 |
153 | $('.templating', self.form).removeClass('focus');
154 | base_element.addClass('focus').focus();
155 | }
156 |
157 | // Load currently focused form if enter or escape is hit
158 | if (key == 13 || key == 27) {
159 | self.processForm();
160 | }
161 | });
162 | };
163 |
164 | /**
165 | * Load a template by double clicking it.
166 | * @param dialog
167 | */
168 | XMLTemplates.prototype.loadEvents = function(dialog) {
169 | var self = this;
170 |
171 | this.focusTemplate();
172 |
173 | this.form.on('dblclick', function() {
174 | self.processForm();
175 | });
176 | };
177 |
--------------------------------------------------------------------------------
/lib/ace/src-min/keybinding-emacs.js:
--------------------------------------------------------------------------------
1 | define("ace/keyboard/emacs",["require","exports","module","ace/lib/dom","ace/keyboard/hash_handler","ace/lib/keys"],function(a,b,c){var d=a("../lib/dom"),e=function(a,b){var c=this.scroller.getBoundingClientRect(),e=Math.floor((a+this.scrollLeft-c.left-this.$padding-d.getPageScrollLeft())/this.characterWidth),f=Math.floor((b+this.scrollTop-c.top-d.getPageScrollTop())/this.lineHeight);return this.session.screenToDocumentPosition(f,e)},f=a("./hash_handler").HashHandler;b.handler=new f;var g=!1;b.handler.attach=function(a){g||(g=!0,d.importCssString(" .emacs-mode .ace_cursor{ border: 2px rgba(50,250,50,0.8) solid!important; -moz-box-sizing: border-box!important; box-sizing: border-box!important; background-color: rgba(0,250,0,0.9); opacity: 0.5; } .emacs-mode .ace_cursor.ace_hidden{ opacity: 1; background-color: transparent; } .emacs-mode .ace_cursor.ace_overwrite { opacity: 1; background-color: transparent; border-width: 0 0 2px 2px !important; } .emacs-mode .ace_text-layer { z-index: 4 } .emacs-mode .ace_cursor-layer { z-index: 2 }","emacsMode")),a.renderer.screenToTextCoordinates=e,a.setStyle("emacs-mode")},b.handler.detach=function(a){delete a.renderer.screenToTextCoordinates,a.unsetStyle("emacs-mode")};var h=a("../lib/keys").KEY_MODS,i={C:"ctrl",S:"shift",M:"alt"};["S-C-M","S-C","S-M","C-M","S","C","M"].forEach(function(a){var b=0;a.split("-").forEach(function(a){b|=h[i[a]]}),i[b]=a.toLowerCase()+"-"}),b.handler.bindKey=function(a,b){if(!a)return;var c=this.commmandKeyBinding;a.split("|").forEach(function(a){a=a.toLowerCase(),c[a]=b,a=a.split(" ")[0],c[a]||(c[a]="null")},this)},b.handler.handleKeyboard=function(a,b,c,d){if(b==-1&&a.count){var e=Array(a.count+1).join(c);return a.count=null,{command:"insertstring",args:e}}if(c=="\0")return;var f=i[b];if(f=="c-"||a.universalArgument){var g=parseInt(c[c.length-1]);if(g)return a.count=g,{command:"null"}}a.universalArgument=!1,f&&(c=f+c),a.keyChain&&(c=a.keyChain+=" "+c);var h=this.commmandKeyBinding[c];a.keyChain=h=="null"?c:"";if(!h)return;if(h=="null")return{command:"null"};if(h=="universalArgument")return a.universalArgument=!0,{command:"null"};if(typeof h!="string"){var j=h.args;h=h.command}typeof h=="string"&&(h=this.commands[h]||a.editor.commands.commands[h]),!h.readonly&&!h.isYank&&(a.lastCommand=null);if(a.count){var g=a.count;return a.count=0,{args:j,command:{exec:function(a,b){for(var c=0;c30&&this.$data.shift()},get:function(){return this.$data[this.$data.length-1]||""},pop:function(){return this.$data.length>1&&this.$data.pop(),this.get()},rotate:function(){return this.$data.unshift(this.$data.pop()),this.get()}}})
--------------------------------------------------------------------------------
/demo/examples/spoonful_of_mods.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A Spoonful of Math Helps The Medicine Go Down:
5 | An Illustration of How Healthcare Can Benefit From Mathematical Modeling and Analysis
6 |
7 | Abstract
8 |
9 |
10 |
11 | Objectives
12 |
13 | A recent joint report from the Institute of Medicine and the National Academy of Engineering, highlights the benefits of--indeed, the need for--mathematical analysis of healthcare delivery. Tools for such analysis have been developed over decades by researchers in Operations Research (OR). An OR perspective typically frames a complex problem in terms of its essential mathematical structure. This article illustrates the use and value of the tools of operations research in healthcare. It reviews one OR tool, queueing theory, and provides an illustration involving a hypothetical drug treatment facility.
14 |
15 |
16 |
17 | Method
18 |
19 | Queueing Theory (QT) is the study of waiting lines. The theory is useful in that it provides solutions to problems of waiting and its relationship to key characteristics of healthcare systems. More generally, it illustrates the strengths of modeling in healthcare and service delivery.
20 | Queueing theory offers insights that initially may be hidden. For example, a queueing model allows one to incorporate randomness, which is inherent in the actual system, into the mathematical analysis. As a result of this randomness, these systems often perform much worse than one might have guessed based on deterministic conditions. Poor performance is reflected in longer lines, longer waits, and lower levels of server utilization.
21 | As an illustration, we specify a queueing model of a representative drug treatment facility. The analysis of this model provides mathematical expressions for some of the key performance measures, such as average waiting time for admission.
22 |
23 |
24 |
25 | Results
26 |
27 | We calculate average occupancy in the facility and its relationship to system characteristics. For example, when the facility has 28 beds, the average wait for admission is 4 days. We also explore the relationship between arrival rate at the facility, the capacity of the facility, and waiting times.
28 |
29 |
30 |
31 | Conclusions
32 |
33 | One key aspect of the healthcare system is its complexity, and policy makers want to design and reform the system in a way that affects competing goals. OR methodologies, particularly queueing theory, can be very useful in gaining deeper understanding of this complexity and exploring the potential effects of proposed changes on the system without making any actual changes.
34 |
35 | eng
36 |
37 | text
38 | Journal Article
39 |
40 | BioMed Central Ltd
41 | 2010-06-23
42 |
43 | Peer Reviewed
44 |
45 |
46 |
47 | E Michael Foster et al.; licensee BioMed Central Ltd.
48 |
49 |
50 |
51 |
52 | Open Access
53 | BMC Medical Research Methodology. 2010 Jun 23;10(1):60
54 |
55 | http://dx.doi.org/10.1186/1471-2288-10-60
56 |
57 | 10.1186/1471-2288-10-60
58 | 20573235
59 |
60 | Foster, E Michael
61 | Department of Maternal and Child Health, UNC Gillings School of Global Public Health, University of North Carolina at Chapel Hill
62 |
63 |
64 | Hosking, Michael R
65 | Department of Statistics and Operations Research, UNC College of Arts & Sciences, University of North Carolina at Chapel Hill
66 |
67 |
68 | Ziya, Serhan
69 | Department of Statistics and Operations Research, UNC College of Arts & Sciences, University of North Carolina at Chapel Hill
70 |
71 |
72 |
73 | BMC Medical Research Methodology
74 |
75 | 1471-2288
76 |
77 | 2010
78 |
79 |
80 |
81 | 10
82 | vol.
83 |
84 |
85 | 1
86 | issue
87 |
88 |
89 |
90 |
91 | 60
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/src/abstract_xml_object.js:
--------------------------------------------------------------------------------
1 | function AbstractXMLObject(objectType, editor) {
2 | this.editor = editor;
3 | this.guiEditor = this.editor.guiEditor;
4 | this.objectType = objectType;
5 |
6 | // ID of the dom node for this element
7 | this.domNodeID = null;
8 | // dom node for this element
9 | this.domNode = null;
10 | // XMLElement which is the parent of this element
11 | this.parentElement = null;
12 | // Main input for text node of this element
13 | this.textInput = null;
14 | }
15 |
16 | // Generates input fields for elements and attributes, depending on the type of value in the definition
17 | // inputID - id attribute for the new input field
18 | // startingValue - initial value for the new input
19 | // appendTarget - DOM element which the new input will be append to
20 | AbstractXMLObject.prototype.createElementInput = function (inputID, startingValue, appendTarget){
21 | if (startingValue === undefined)
22 | startingValue = "";
23 | var input = null;
24 | var $input = null;
25 | // Select input for fields with a predefined set of values
26 | if (this.objectType.values && this.objectType.values.length > 0){
27 | var selectionValues = this.objectType.values;
28 | input = document.createElement('select');
29 | input.id = inputID;
30 | input.className = 'xml_select';
31 | appendTarget.appendChild(input);
32 |
33 | for (var index in selectionValues) {
34 | var selectionValue = selectionValues[index];
35 | var option = new Option(selectionValue.toString(), selectionValue);
36 | input.options[index] = option;
37 | if (startingValue == selectionValue) {
38 | input.options[index].selected = true;
39 | }
40 | }
41 | if ((startingValue == " ") || (startingValue == ""))
42 | input.selectedIndex = -1;
43 | $input = $(input);
44 | } // Text area for normal elements and string attributes
45 | else if ((this.objectType.text && (this.objectType.type == 'string' || this.objectType.type == 'mixed'))
46 | || this.objectType.attribute || this.objectType.cdata || this.objectType.comment){
47 | input = document.createElement('textarea');
48 | input.id = inputID;
49 | input.className = 'xml_textarea';
50 | // Text areas start out with a space so that the pretty formating won't collapse the field
51 | input.value = startingValue? startingValue : " ";
52 | appendTarget.appendChild(input);
53 |
54 | $input = $(input);
55 | var self = this;
56 | // Clear out the starting space on first focus. This space is there to prevent field collapsing
57 | // on new elements in the text editor view
58 | $input.one('focus', function() {
59 | if (self.editor.options.expandingTextAreas)
60 | $input.autosize();
61 | if (this.value == " ")
62 | this.value = "";
63 | });
64 | } else if (this.objectType.type == 'date'){
65 | // Some browsers support the date input type at this point. If not, it just behaves as text
66 | input = document.createElement('input');
67 | input.type = 'date';
68 | input.id = inputID;
69 | input.className = 'xml_date';
70 | input.value = startingValue? startingValue : "";
71 | appendTarget.appendChild(input);
72 |
73 | $input = $(input);
74 | } else if (this.objectType.type){
75 | input = document.createElement('input');
76 | if (this.objectType.type == 'date') {
77 | // Some browsers support the date input type. If not, it should behaves as text
78 | input.type = 'date';
79 | input.className = 'xml_date';
80 | } else if (this.objectType.type == 'dateTime') {
81 | // May not be supported by browsers yet
82 | input.type = 'datetime';
83 | input.className = 'xml_datetime';
84 | } else {
85 | // All other types as text for now
86 | input.type = 'text';
87 | input.className = 'xml_input';
88 | }
89 | input.id = inputID;
90 | input.value = startingValue? startingValue : "";
91 | appendTarget.appendChild(input);
92 |
93 | $input = $(input);
94 | }
95 | return $input;
96 | };
97 |
98 | // Change the editors focus to this xml object
99 | AbstractXMLObject.prototype.focus = function() {
100 | if (this.domNode != null)
101 | this.guiEditor.focusObject(this.domNode);
102 | if (this.textInput)
103 | this.textInput.focus();
104 | };
105 |
106 | AbstractXMLObject.prototype.getDomNode = function () {
107 | return this.domNode;
108 | };
109 |
110 | // Remove this element from the xml document and editor
111 | AbstractXMLObject.prototype.remove = function() {
112 | // Remove the element from the xml doc
113 | this.xmlNode.remove();
114 |
115 | if (this.domNode != null) {
116 | this.domNode.remove();
117 | }
118 | };
119 |
120 | // Swap the gui representation of this element to the location of swapTarget
121 | AbstractXMLObject.prototype.swap = function (swapTarget) {
122 | if (swapTarget == null) {
123 | return;
124 | }
125 |
126 | // Swap the xml nodes
127 | swapTarget.xmlNode.detach().insertAfter(this.xmlNode);
128 | if (swapTarget.domNode != null && this.domNode != null) {
129 | // Swap the gui nodes
130 | swapTarget.domNode.detach().insertAfter(this.domNode);
131 | }
132 | };
133 |
134 | // Move this element up one location in the gui. Returns true if the swap was able to happen
135 | AbstractXMLObject.prototype.moveUp = function() {
136 | var previousSibling = this.domNode.prev("." + xmlNodeClass);
137 | if (previousSibling.length > 0) {
138 | this.swap(previousSibling.data("xmlObject"));
139 | return true;
140 | } else {
141 | return false;
142 | }
143 | };
144 |
145 | // Move this element down one location in the gui. Returns true if the swap was able to happen
146 | AbstractXMLObject.prototype.moveDown = function() {
147 | var nextSibling = this.domNode.next("." + xmlNodeClass);
148 | if (nextSibling.length > 0) {
149 | nextSibling.data("xmlObject").swap(this);
150 | return true;
151 | } else {
152 | return false;
153 | }
154 | };
155 |
156 | AbstractXMLObject.prototype.select = function() {
157 | this.domNode.addClass("selected");
158 | };
159 |
160 | AbstractXMLObject.prototype.isSelected = function() {
161 | return this.domNode.hasClass("selected");
162 | };
--------------------------------------------------------------------------------
/src/modify_element_menu.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Menu object for adding new elements to an existing element or document
3 | */
4 | function ModifyElementMenu(menuID, label, expanded, enabled, owner, editor, getRelativeToFunction) {
5 | this.menuID = menuID;
6 | this.label = label;
7 | // Header jquery element for this menu
8 | this.menuHeader = null;
9 | // Refence to jquery object which contains the menu options
10 | this.menuContent = null;
11 | // Indicates if the menu can be interacted with
12 | this.enabled = enabled;
13 | // Indicates if the menu is collapsed or expanded
14 | this.expanded = expanded;
15 | // Optional function which determines what element to position newly added elements relative to
16 | this.getRelativeToFunction = getRelativeToFunction;
17 | // XMLElement object which will be modified by this menu
18 | this.target = null;
19 | this.owner = owner;
20 | this.editor = editor;
21 | }
22 |
23 | ModifyElementMenu.prototype.destroy = function() {
24 | if (this.menuHeader != null)
25 | this.menuHeader.remove();
26 | if (this.menuContent != null)
27 | this.menuContent.remove();
28 | };
29 |
30 | // Creates the structure for the menu, including headers and content areas.
31 | ModifyElementMenu.prototype.render = function(parentContainer) {
32 | this.menuHeader = $("").appendTo(parentContainer);
33 | if (this.expanded) {
34 | this.menuHeader.html(this.label + " ▼");
35 | } else {
36 | this.menuHeader.html(this.label + " ▶");
37 | }
38 |
39 | if (!this.enabled)
40 | this.menuHeader.addClass("disabled");
41 |
42 | this.menuContent = $("").data('menuData', this).appendTo(parentContainer);
43 | var self = this;
44 | // Click handler for hiding/show the contents of the menu
45 | this.menuHeader.click(function(){
46 | if (!self.enabled)
47 | return;
48 | if (self.expanded) {
49 | self.menuContent.animate({height: 'hide'}, menuExpandDuration, null, function(){
50 | self.menuContent.hide();
51 | });
52 | self.menuHeader.html(self.label + " ▶");
53 | self.expanded = false;
54 | } else {
55 | self.menuContent.show();
56 | self.menuContent.animate({height: 'show'}, menuExpandDuration);
57 | self.menuHeader.html(self.label + " ▼");
58 | self.expanded = true;
59 | }
60 | });
61 | return this;
62 | };
63 |
64 | ModifyElementMenu.prototype.initEventHandlers = function() {
65 | var self = this;
66 | // Add new child element click event
67 | this.menuContent.on('click', 'li', function(event){
68 | var relativeTo = (self.getRelativeToFunction)?
69 | self.getRelativeToFunction($(this).data("xml").target) : null;
70 | var prepend = self.editor.options.prependNewElements;
71 | if (event.shiftKey) prepend = !prepend;
72 | self.owner.editor.addChildElementCallback(this, relativeTo, prepend);
73 | });
74 | };
75 |
76 | // Empty out the menu and collapse it
77 | ModifyElementMenu.prototype.clear = function() {
78 | var startingHeight = this.menuContent.height();
79 | this.menuContent.empty();
80 | this.menuContent.css({height: startingHeight + "px"}).stop().animate({height: "0px"}, menuExpandDuration);
81 | this.target = null;
82 | this.enabled = false;
83 | this.menuHeader.addClass('disabled');
84 | return this;
85 | };
86 |
87 | // Populate the menu with entries for adding child elements of from the definition of the given XMLElement
88 | ModifyElementMenu.prototype.populate = function(xmlElement) {
89 | if (xmlElement == null || (this.target != null && xmlElement.domNode != null
90 | && this.target[0] === xmlElement.domNode[0]))
91 | return;
92 |
93 | if (this.expanded)
94 | this.menuContent.css("height", "auto");
95 | // Store the current height of the menu for use animating the height changes
96 | var startingHeight = this.menuContent.outerHeight();
97 | // Clear the previous menu contents
98 | this.menuContent.empty();
99 |
100 | // Store new target element for this menu
101 | this.target = xmlElement;
102 | var self = this;
103 | var parent = this.target;
104 | var choiceList = parent.objectType.choices;
105 |
106 | // Iterate through the child element definitions and generate entries for each
107 | if (this.target.objectType.elements) {
108 | $.each(this.target.objectType.elements, function(){
109 | var xmlElement = this;
110 | var elName = self.editor.xmlState.getNamespacePrefix(xmlElement.namespace) + xmlElement.localName;
111 | var addButton = $("").attr({
112 | title : 'Add ' + elName
113 | }).html(elName)
114 | .data('xml', {
115 | "target": self.target,
116 | "objectType": xmlElement
117 | }).appendTo(self.menuContent);
118 | // Disable the entry if its parent won't allow any more of this element type.
119 | if (!parent.childCanBeAdded(xmlElement))
120 | addButton.addClass('disabled');
121 | });
122 | }
123 |
124 | if (this.target.objectType.any) {
125 | $.each(this.editor.guiEditor.rootElement.objectType.elements, function() {
126 | var xmlElement = this;
127 | var elName = self.editor.xmlState.getNamespacePrefix(xmlElement.namespace) + xmlElement.localName;
128 | var addButton = $("").attr({
129 | title : 'Add ' + elName
130 | }).html(elName)
131 | .data('xml', {
132 | "target": self.target,
133 | "objectType": xmlElement
134 | }).appendTo(self.menuContent);
135 | });
136 | }
137 |
138 | if (this.expanded) {
139 | var endingHeight = this.menuContent.outerHeight() + 1;
140 | if (endingHeight == 0)
141 | endingHeight = 1;
142 | this.menuContent.css({height: startingHeight + "px"}).stop().animate({height: endingHeight + "px"}, menuExpandDuration).show();
143 | }
144 |
145 | // Disable or enable the menu depending on if it had any options added to it
146 | if (this.menuContent.children().length == 0) {
147 | this.menuHeader.addClass("disabled");
148 | this.enabled = false;
149 | } else {
150 | this.menuHeader.removeClass("disabled");
151 | this.enabled = true;
152 | }
153 | return this;
154 | };
155 |
--------------------------------------------------------------------------------
/src/xml_element_stub.js:
--------------------------------------------------------------------------------
1 | function XMLElementStub(editor) {
2 | this.objectType = {
3 | elementStub : true
4 | };
5 | this.editor = editor;
6 | this.guiEditor = this.editor.guiEditor;
7 | // dom element header for this element
8 | this.elementHeader = null;
9 | // dom element which contains the display of child nodes
10 | this.nameInput = null;
11 |
12 | this.tagName = "";
13 | }
14 |
15 | XMLElementStub.prototype.render = function(parentElement, prepend, relativeToXMLElement) {
16 | this.parentElement = parentElement;
17 | this.domNodeID = this.guiEditor.nextIndex();
18 |
19 | // Create the element and add it to the container
20 | this.domNode = document.createElement('div');
21 | var $domNode = $(this.domNode);
22 | this.domNode.id = this.domNodeID;
23 | this.domNode.className = 'xml_node xml_stub ' + xmlElementClass;
24 | if (this.isTopLevel)
25 | this.domNode.className += ' ' + topLevelContainerClass;
26 | if (this.parentElement) {
27 | if (relativeToXMLElement) {
28 | if (prepend)
29 | $domNode.insertBefore(relativeToXMLElement.domNode);
30 | else
31 | $domNode.insertAfter(relativeToXMLElement.domNode);
32 | } else {
33 | if (prepend)
34 | this.parentElement.nodeContainer.prepend(this.domNode);
35 | else
36 | this.parentElement.nodeContainer[0].appendChild(this.domNode);
37 | }
38 | }
39 |
40 | // Begin building contents
41 | this.elementHeader = document.createElement('ul');
42 | this.elementHeader.className = 'element_header';
43 | this.domNode.appendChild(this.elementHeader);
44 | var elementNameContainer = document.createElement('li');
45 | elementNameContainer.className = 'element_name';
46 | this.elementHeader.appendChild(elementNameContainer);
47 |
48 | // set up element title and entry field if appropriate
49 | this.nameInput = $("");
50 | this.nameInput.appendTo(elementNameContainer);
51 |
52 | var self = this;
53 |
54 | var createLink = $("create element").appendTo(elementNameContainer).mouseup(function(e){
55 | self.create();
56 | });
57 |
58 |
59 | this.elementHeader.appendChild(this.addTopActions(this.domNodeID));
60 |
61 | this.domNode = $domNode;
62 | this.domNode.data("xmlObject", this);
63 |
64 | stubNameInput.call(this, this.nameInput, parentElement.objectType.elements);
65 | };
66 |
67 | function stubNameInput(nameInput, suggestionList, validItemFunction) {
68 | var self = this;
69 | var autocompleteEnabled = false;
70 |
71 | nameInput.keydown(function(e) {
72 | // escape, cancel
73 | if (e.keyCode == 27) {
74 | if (autocompleteEnabled && $(nameInput.xml_autocomplete('widget')).is(':visible')) {
75 | nameInput.xml_autocomplete('close');
76 | } else {
77 | self.remove();
78 | self.guiEditor.selectNode(self.parentElement);
79 | var containingNode = self.parentElement? self.parentElement : self.xmlElement;
80 | containingNode.updated({action : 'childRemoved', target : self});
81 | }
82 | return false;
83 | }
84 |
85 | // Enter, create
86 | if (e.keyCode == 13) {
87 | self.create();
88 | return false;
89 | }
90 |
91 | // Prevent spaces
92 | if (e.keyCode == 32) {
93 | return false;
94 | }
95 |
96 | // Block propagation of text editing keys
97 | if (e.which >= 37 && e.which <= 40 || e.which == 46) {
98 | e.stopPropagation();
99 | }
100 | });
101 |
102 | var initializedAutocomplete = false;
103 |
104 | nameInput.focus(function(e) {
105 | // Activate autocompletion dropdown for possible child elements defined in schema
106 | if (!initializedAutocomplete && suggestionList && suggestionList.length > 0) {
107 | var suggDefs = [];
108 | var xmlState = self.editor.xmlState;
109 |
110 | for (var i in suggestionList) {
111 | var definition = suggestionList[i];
112 | suggDefs.push(xmlState.getNamespacePrefix(definition.namespace) + definition.localName);
113 | }
114 |
115 | nameInput.xml_autocomplete({
116 | source : suggDefs,
117 | minLength: 0,
118 | delay: 0,
119 | matchSize : nameInput,
120 | validItemFunction : validItemFunction,
121 | select : function(e, ui) {
122 | self.nameInput.text(ui.item.value);
123 | self.create();
124 | }
125 | });
126 | autocompleteEnabled = true;
127 | initializedAutocomplete = true;
128 | }
129 |
130 | if (autocompleteEnabled){
131 | nameInput.xml_autocomplete("search", nameInput.text());
132 | }
133 | e.stopPropagation();
134 | }).mousedown(function(e) {
135 | nameInput.focus();
136 | e.stopPropagation();
137 | });
138 | }
139 |
140 | XMLElementStub.prototype.addTopActions = function () {
141 | var self = this;
142 | var topActionSpan = document.createElement('li');
143 | topActionSpan.className = 'top_actions';
144 |
145 | var deleteButton = document.createElement('span');
146 | deleteButton.className = 'xml_delete';
147 | deleteButton.id = this.domNodeID + '_del';
148 | deleteButton.appendChild(document.createTextNode('X'));
149 | topActionSpan.appendChild(deleteButton);
150 |
151 | return topActionSpan;
152 | };
153 |
154 | XMLElementStub.prototype.remove = function() {
155 | this.domNode.remove();
156 | };
157 |
158 | XMLElementStub.prototype.create = function() {
159 | var tagName = this.nameInput.text();
160 |
161 | var nextSiblings = this.domNode.nextAll(".xml_node:not(.xml_stub)");
162 | var relativeTo = null;
163 | if (nextSiblings.length > 0) {
164 | relativeTo = nextSiblings.first().data("xmlObject");
165 | }
166 |
167 | var newElement = this.editor.addChildElement(this.parentElement, tagName, relativeTo, relativeTo != null);
168 | if (newElement instanceof AbstractXMLObject) {
169 | // Move new element to match display position of the stub, in case it was misplaced because of its siblings being stubs
170 | newElement.domNode.detach();
171 | this.domNode.after(newElement.domNode);
172 | this.remove();
173 | this.guiEditor.focusSelectedText(newElement);
174 | } else {
175 | console.log(newElement);
176 | }
177 | };
178 |
179 | XMLElementStub.prototype.getSelectedAttribute = function () {
180 | return [];
181 | };
182 |
183 | XMLElementStub.prototype.select = function() {
184 | this.domNode.addClass("selected");
185 | };
186 |
187 | XMLElementStub.prototype.isSelected = function() {
188 | return this.domNode.hasClass("selected");
189 | };
190 |
191 | XMLElementStub.prototype.focus = function() {
192 | this.nameInput.focus();
193 | };
--------------------------------------------------------------------------------
/demo/examples/dcterms/xml.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | See http://www.w3.org/XML/1998/namespace.html and
7 | http://www.w3.org/TR/REC-xml for information about this namespace.
8 |
9 | This schema document describes the XML namespace, in a form
10 | suitable for import by other schema documents.
11 |
12 | Note that local names in this namespace are intended to be defined
13 | only by the World Wide Web Consortium or its subgroups. The
14 | following names are currently defined in this namespace and should
15 | not be used with conflicting semantics by any Working Group,
16 | specification, or document instance:
17 |
18 | base (as an attribute name): denotes an attribute whose value
19 | provides a URI to be used as the base for interpreting any
20 | relative URIs in the scope of the element on which it
21 | appears; its value is inherited. This name is reserved
22 | by virtue of its definition in the XML Base specification.
23 |
24 | id (as an attribute name): denotes an attribute whose value
25 | should be interpreted as if declared to be of type ID.
26 | The xml:id specification is not yet a W3C Recommendation,
27 | but this attribute is included here to facilitate experimentation
28 | with the mechanisms it proposes. Note that it is _not_ included
29 | in the specialAttrs attribute group.
30 |
31 | lang (as an attribute name): denotes an attribute whose value
32 | is a language code for the natural language of the content of
33 | any element; its value is inherited. This name is reserved
34 | by virtue of its definition in the XML specification.
35 |
36 | space (as an attribute name): denotes an attribute whose
37 | value is a keyword indicating what whitespace processing
38 | discipline is intended for the content of the element; its
39 | value is inherited. This name is reserved by virtue of its
40 | definition in the XML specification.
41 |
42 | Father (in any context at all): denotes Jon Bosak, the chair of
43 | the original XML Working Group. This name is reserved by
44 | the following decision of the W3C XML Plenary and
45 | XML Coordination groups:
46 |
47 | In appreciation for his vision, leadership and dedication
48 | the W3C XML Plenary on this 10th day of February, 2000
49 | reserves for Jon Bosak in perpetuity the XML name
50 | xml:Father
51 |
52 |
53 |
54 |
55 | This schema defines attributes and an attribute group
56 | suitable for use by
57 | schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
58 | attributes on elements they define.
59 |
60 | To enable this, such a schema must import this schema
61 | for the XML namespace, e.g. as follows:
62 | <schema . . .>
63 | . . .
64 | <import namespace="http://www.w3.org/XML/1998/namespace"
65 | schemaLocation="http://www.w3.org/2001/xml.xsd"/>
66 |
67 | Subsequently, qualified reference to any of the attributes
68 | or the group defined below will have the desired effect, e.g.
69 |
70 | <type . . .>
71 | . . .
72 | <attributeGroup ref="xml:specialAttrs"/>
73 |
74 | will define a type which will schema-validate an instance
75 | element with any of those attributes
76 |
77 |
78 |
79 | In keeping with the XML Schema WG's standard versioning
80 | policy, this schema document will persist at
81 | http://www.w3.org/2005/08/xml.xsd.
82 | At the date of issue it can also be found at
83 | http://www.w3.org/2001/xml.xsd.
84 | The schema document at that URI may however change in the future,
85 | in order to remain compatible with the latest version of XML Schema
86 | itself, or with the XML namespace itself. In other words, if the XML
87 | Schema or XML namespaces change, the version of this document at
88 | http://www.w3.org/2001/xml.xsd will change
89 | accordingly; the version at
90 | http://www.w3.org/2005/08/xml.xsd will not change.
91 |
92 |
93 |
94 |
95 |
96 | Attempting to install the relevant ISO 2- and 3-letter
97 | codes as the enumerated possible values is probably never
98 | going to be a realistic possibility. See
99 | RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
100 | at http://www.iana.org/assignments/lang-tag-apps.htm for
101 | further information.
102 |
103 | The union allows for the 'un-declaration' of xml:lang with
104 | the empty string.
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | See http://www.w3.org/TR/xmlbase/ for
129 | information about this attribute.
130 |
131 |
132 |
133 |
134 |
135 | See http://www.w3.org/TR/xml-id/ for
136 | information about this attribute.
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/demo/examples/eac-cpf/xml.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | See http://www.w3.org/XML/1998/namespace.html and
7 | http://www.w3.org/TR/REC-xml for information about this namespace.
8 |
9 | This schema document describes the XML namespace, in a form
10 | suitable for import by other schema documents.
11 |
12 | Note that local names in this namespace are intended to be defined
13 | only by the World Wide Web Consortium or its subgroups. The
14 | following names are currently defined in this namespace and should
15 | not be used with conflicting semantics by any Working Group,
16 | specification, or document instance:
17 |
18 | base (as an attribute name): denotes an attribute whose value
19 | provides a URI to be used as the base for interpreting any
20 | relative URIs in the scope of the element on which it
21 | appears; its value is inherited. This name is reserved
22 | by virtue of its definition in the XML Base specification.
23 |
24 | id (as an attribute name): denotes an attribute whose value
25 | should be interpreted as if declared to be of type ID.
26 | The xml:id specification is not yet a W3C Recommendation,
27 | but this attribute is included here to facilitate experimentation
28 | with the mechanisms it proposes. Note that it is _not_ included
29 | in the specialAttrs attribute group.
30 |
31 | lang (as an attribute name): denotes an attribute whose value
32 | is a language code for the natural language of the content of
33 | any element; its value is inherited. This name is reserved
34 | by virtue of its definition in the XML specification.
35 |
36 | space (as an attribute name): denotes an attribute whose
37 | value is a keyword indicating what whitespace processing
38 | discipline is intended for the content of the element; its
39 | value is inherited. This name is reserved by virtue of its
40 | definition in the XML specification.
41 |
42 | Father (in any context at all): denotes Jon Bosak, the chair of
43 | the original XML Working Group. This name is reserved by
44 | the following decision of the W3C XML Plenary and
45 | XML Coordination groups:
46 |
47 | In appreciation for his vision, leadership and dedication
48 | the W3C XML Plenary on this 10th day of February, 2000
49 | reserves for Jon Bosak in perpetuity the XML name
50 | xml:Father
51 |
52 |
53 |
54 |
55 | This schema defines attributes and an attribute group
56 | suitable for use by
57 | schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
58 | attributes on elements they define.
59 |
60 | To enable this, such a schema must import this schema
61 | for the XML namespace, e.g. as follows:
62 | <schema . . .>
63 | . . .
64 | <import namespace="http://www.w3.org/XML/1998/namespace"
65 | schemaLocation="http://www.w3.org/2001/xml.xsd"/>
66 |
67 | Subsequently, qualified reference to any of the attributes
68 | or the group defined below will have the desired effect, e.g.
69 |
70 | <type . . .>
71 | . . .
72 | <attributeGroup ref="xml:specialAttrs"/>
73 |
74 | will define a type which will schema-validate an instance
75 | element with any of those attributes
76 |
77 |
78 |
79 | In keeping with the XML Schema WG's standard versioning
80 | policy, this schema document will persist at
81 | http://www.w3.org/2005/08/xml.xsd.
82 | At the date of issue it can also be found at
83 | http://www.w3.org/2001/xml.xsd.
84 | The schema document at that URI may however change in the future,
85 | in order to remain compatible with the latest version of XML Schema
86 | itself, or with the XML namespace itself. In other words, if the XML
87 | Schema or XML namespaces change, the version of this document at
88 | http://www.w3.org/2001/xml.xsd will change
89 | accordingly; the version at
90 | http://www.w3.org/2005/08/xml.xsd will not change.
91 |
92 |
93 |
94 |
95 |
96 | Attempting to install the relevant ISO 2- and 3-letter
97 | codes as the enumerated possible values is probably never
98 | going to be a realistic possibility. See
99 | RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
100 | at http://www.iana.org/assignments/lang-tag-apps.htm for
101 | further information.
102 |
103 | The union allows for the 'un-declaration' of xml:lang with
104 | the empty string.
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | See http://www.w3.org/TR/xmlbase/ for
129 | information about this attribute.
130 |
131 |
132 |
133 |
134 |
135 | See http://www.w3.org/TR/xml-id/ for
136 | information about this attribute.
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------