24                     "options": ["lewo", "srodek", "prawo"],
 
  41     class PropertiesPerspective extends $.wiki.SidebarPerspective {
 
  42         vsplitbar = 'WŁAŚCIWOŚCI';
 
  45         constructor(options) {
 
  49                 self.$pane = $("#side-properties");
 
  51                 $("#simple-editor").on('click', '[x-node]', function(e) {
 
  52                     if (!e.redakcja_edited) {
 
  53                         e.redakcja_edited = true;
 
  58                 self.$pane.on('click', '#parents li', function(e) {
 
  59                     self.edit($(this).data('node'));
 
  62                 $(document).on('click', '#bubbles .badge', function(e) {
 
  63                     self.edit($(this).data('node'));
 
  66                 self.$pane.on('change', '.form-control', function() {
 
  70                     if ($input.attr('type') == 'checkbox') {
 
  71                         inputval = $input.is(':checked');
 
  73                         inputval = $input.val();
 
  76                     if ($input.data("edited")) {
 
  77                         if ($input.data("edited-attr")) {
 
  78                             $input.data("edited").attr($input.data("edited-attr"), inputval);
 
  80                             $input.data("edited").text(inputval);
 
  82                         $.wiki.perspectives.VisualPerspective.flush();
 
  87                         element: self.$edited[0],
 
  88                         success: function(xml) {
 
  90                             let $xmlelem = $($.parseXML(xml));
 
  92                             w($input.data('property'), $input.val());
 
  93                             $xmlelem.contents().attr($input.data('property'), inputval);
 
  95                             let newxml = (new XMLSerializer()).serializeToString($xmlelem[0]);
 
  99                                 base: self.doc.getBase(),
 
 100                                 success: function(html) {
 
 101                                     let htmlElem = $(html);
 
 102                                     self.$edited.replaceWith(htmlElem);
 
 104                                     $.wiki.activePerspective().flush();
 
 108                         error: function(e) {console.log(e);},
 
 114                 self.$pane.on('click', '.meta-add', function() {
 
 115                     // create a metadata item
 
 116                     let $fg = $(this).parent();
 
 117                     let ns = $fg.data('ns');
 
 118                     let tag = $fg.data('tag');
 
 119                     let field = $fg.data('field');
 
 120                     let span = $('<span/>');
 
 121                     span.attr('x-node', tag);
 
 122                     span.attr('x-ns', ns)
 
 123                     if (field.value_type.hasLanguage) {
 
 124                         span.attr('x-a-xml-lang', 'pl');
 
 127                     let rdf = $("> [x-node='RDF']", self.$edited);
 
 129                         rdf = $("<span x-node='RDF' x-ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>");
 
 130                         self.$edited.prepend(rdf);
 
 131                         self.$edited.prepend('\n  ');
 
 134                     let rdfdesc = $("> [x-node='Description']", rdf);
 
 135                     if (!rdfdesc.length) {
 
 136                         rdfdesc = $("<span x-node='Description' x-ns='http://www.w3.org/1999/02/22-rdf-syntax-ns#' x-a-rdf-about='" + self.doc.fullUri + "'>");
 
 137                         rdf.prepend(rdfdesc);
 
 139                         rdfdesc.append('\n    ');
 
 142                     span.appendTo(rdfdesc);
 
 143                     rdfdesc.append('\n    ');
 
 145                     self.displayMetaProperty($fg);
 
 150                 self.$pane.on('click', '.meta-delete', function() {
 
 151                     let $fg = $(this).closest('.form-group');
 
 152                     let $ig = $(this).closest('.input-group');
 
 153                     $('input', $ig).data('edited').remove();
 
 154                     self.displayMetaProperty($fg);
 
 155                     $.wiki.perspectives.VisualPerspective.flush();
 
 159                 $('#media-chooser').on('show.bs.modal', function (event) {
 
 160                     var input = $("input", $(event.relatedTarget).parent());
 
 162                     modal.data('target-input', input);
 
 163                     var imglist = modal.find('.modal-body');
 
 165                     $.each(self.doc.galleryImages, (i, imgItem) => {
 
 166                         img = $("<img>").attr("src", imgItem.thumb).attr('title', imgItem.url).data('url', imgItem.url).on('click', function() {
 
 167                             imglist.find('img').removeClass('active');
 
 168                             $(this).addClass('active');
 
 173                 $('#media-chooser .ctrl-ok').on('click', function (event) {
 
 174                     $('#media-chooser').data('target-input')
 
 176                             (new URL($('#media-chooser .active').data('url'), document.baseURI)).href
 
 178                     $('#media-chooser').modal('hide');
 
 181                 self.$pane.on('click', '.current-convert', function() {
 
 182                     self.convert($(this).attr('data-to'));
 
 184                 self.$pane.on('click', '#current-delete', function() {
 
 192             $("#parents", self.$pane).empty();
 
 193             $("#bubbles").empty();
 
 195             let $f = $("#properties-form", self.$pane);
 
 198             if (element === null) {
 
 200                 $("h1", self.$pane).text('');
 
 204             let $node = $(element);
 
 205             let b = $("<div class='badge badge-primary'></div>").text($node.attr('x-node'));
 
 206             b.data('node', element);
 
 207             $("#bubbles").append(b);
 
 209             $node.parents('[x-node]').each(function() {
 
 210                 let a = $("<li class='breadcrumb-item'>").text($(this).attr('x-node'));
 
 211                 a.data('node', this);
 
 212                 $("#parents", self.$pane).prepend(a)
 
 214                 let b = $("<div class='badge badge-info'></div>").text($(this).attr('x-node'));
 
 215                 b.data('node', this);
 
 216                 $("#bubbles").append(b);
 
 220             let node = $(element).attr('x-node');
 
 221             $("h1", self.$pane).text(node);
 
 223             self.$edited = $(element);
 
 225             let nodeDef = elementDefs[node];
 
 226             if (nodeDef && nodeDef.attributes) {
 
 227                 $.each(nodeDef.attributes, function(i, a) {
 
 228                     self.addEditField(a, $(element).attr('x-a-wl-' + a.name)); // ...
 
 232             // Only utwor can has matadata now.
 
 233             if (node == 'utwor') {
 
 234                 $('<hr>').appendTo($("#properties-form", self.$pane))
 
 235                 META_FIELDS.forEach(function(field) {
 
 236                     let $fg = $("<div class='form-group'>");
 
 237                     $("<label/>").text(field.name).appendTo($fg);
 
 240                     $("<button class='meta-add float-right btn btn-primary'>+</button>").appendTo($fg);
 
 242                     let match = field.uri.match(/({(.*)})?(.*)/);
 
 246                     let cont = $('<div class="c">');
 
 249                     $fg.data('tag', tag);
 
 250                     $fg.data('field', field);
 
 253                     self.displayMetaProperty($fg);
 
 255                     $fg.appendTo( $("#properties-form", self.$pane));
 
 259             // check node type, find relevant tags
 
 260             if ($node[0].nodeName == 'DIV') {
 
 261                 $("#current-convert").attr("data-current-type", "div");
 
 262             } else if ($node[0].nodeName == 'EM') {
 
 263                 $("#current-convert").attr("data-current-type", "span");
 
 267         addMetaInput(cont, field, element) {
 
 270             let ig = $('<div class="input-group">');
 
 271             //ig.data('edited', element);
 
 274             if (field.value_type.hasLanguage) {
 
 275                 let pp = $("<div class='input-group-prepend'>");
 
 276                 let lang_input = $("<input class='form-control' size='1' class='lang'>");
 
 277                 lang_input.data('edited', $(element));
 
 278                 lang_input.data('edited-attr', 'x-a-xml-lang');
 
 280                     $(element).attr('x-a-xml-lang')
 
 282                 lang_input.appendTo(pp);
 
 287             if (field.value_type.widget == 'select') {
 
 288                 $aninput = $("<select class='form-control'>");
 
 289                 $.each(field.value_type.options, function() {
 
 290                     $("<option>").text(this).appendTo($aninput);
 
 293                 $aninput = $("<input class='form-control'>");
 
 294                 if (field.value_type.autocomplete) {
 
 295                     let autoOptions = field.value_type.autocomplete;
 
 296                     $aninput.autocomplete(autoOptions).autocomplete('instance')._renderItem = function(ul, item) {
 
 298                         if (item.name) t += '<br><small><strong>' + item.name + '</strong></small>';
 
 299                         if (item.description) t += '<br><small><em>' + item.description + '</em></small>';
 
 301                             .append( "<div>" + t + "</div>" )
 
 306             $aninput.data('edited', $(element))
 
 310             $aninput.appendTo(ig);
 
 312             let ap = $("<div class='input-group-append'>");
 
 314             $("<button class='meta-delete btn btn-outline-secondary'>x</button>").appendTo(ap);
 
 319         displayMetaProperty($fg) {
 
 321             let ns = $fg.data('ns');
 
 322             let tag = $fg.data('tag');
 
 323             let field = $fg.data('field');
 
 326             $('.c', $fg).empty();
 
 328             let selector = "> [x-node='RDF'] > [x-node='Description'] > [x-node='"+tag+"']";
 
 330                 selector += "[x-ns='"+ns+"']";
 
 332             $(selector, self.$edited).each(function() {
 
 339             let count = $('.c > .input-group', $fg).length;
 
 340             if (field.required) {
 
 342                     $('<div class="text-warning">WYMAGANE</div>').appendTo($('.c', $fg));
 
 347         addEditField(defn, value, elem) {
 
 349             let $form = $("#properties-form", self.$pane);
 
 351             let $fg = $("<div class='form-group'>");
 
 352             $("<label/>").attr("for", "property-" + defn.name).text(defn.name).appendTo($fg);
 
 353             let $input, $inputCnt;
 
 356                 $inputCnt =$input = $("<textarea>");
 
 359                 $inputCnt = $input = $("<select>");
 
 360                 $.each(defn.options, function(i, e) {
 
 361                     $("<option>").text(e).appendTo($input);
 
 365                 $inputCnt = $input = $("<input type='checkbox'>");
 
 368                 $inputCnt = $("<div class='media-input input-group'>");
 
 369                 $input = $("<input type='text'>");
 
 370                 $inputCnt.append($input);
 
 371                 $inputCnt.append($("<button type='button' class='ctrl-media-choose btn btn-primary' data-toggle='modal' data-target='#media-chooser'>…</button>"));
 
 374                 $inputCnt = $input = $("<input>");
 
 377             $input.addClass("form-control").attr("id", "property-" + defn.name).data("property", defn.name);
 
 378             if ($input.attr('type') == 'checkbox') {
 
 379                 $input.prop('checked', value == 'true');
 
 385                 $input.data("edited", elem);
 
 387             $inputCnt.appendTo($fg);
 
 393             this.$edited.attr('x-node', newtag);
 
 394             // TODO: take care of attributes?
 
 398             p = this.$edited.parent();
 
 399             this.$edited.remove();
 
 403         onEnter(success, failure) {
 
 407             if ($.wiki.activePerspective() != 'VisualPerspective')
 
 408                 $.wiki.switchToTab('#VisualPerspective');
 
 414             if (this.$edited === null) {
 
 415                 this.edit($('[x-node="utwor"]')[0]);
 
 422     $.wiki.PropertiesPerspective = PropertiesPerspective;