1/* 2 * Copyright (c) 2024 Republic of Reinvention BV <[email protected]>. All Rights Reserved. 3 * This file is part of project "cinematek-filmout-site" and can not be copied and/or distributed without 4 * the express permission and written consent of the legal responsible of Republic of Reinvention BV. 5 */ 6 7/** 8 * General script to load when a new page is to be created. 9 */ 10base.plugin("blocks.core.Resources", 11 [ 12 "base.core.Class", 13 "constants.base.core", 14 "messages.base.core", 15 "constants.blocks.core", 16 "messages.blocks.core", 17 "base.core.Commons", 18 "blocks.core.Notification" 19 ], 20 function (Class, BaseConstants, BaseMessages, BlocksConstants, BlocksMessages, Commons, Notification) 21 { 22 var Resources = this; 23 24 var newPageCopyInput = $('.' + BlocksConstants.NEW_PAGE_CLASS + ' .actions .copy input'); 25 26 var NEW_PAGE_MAX_RESULTS = 10; 27 var params = {}; 28 params[BlocksConstants.RDF_MAX_RESULTS_PARAM] = NEW_PAGE_MAX_RESULTS; 29 params[BlocksConstants.RDF_PREFIX_SEARCH_PARAM] = true; 30 // the 'prepare' callback below will append to this parameter, so keep it last 31 params[BlocksConstants.RDF_QUERY_PARAM] = ''; 32 33 // init the typeahead plugin 34 var newPageEngine = new Bloodhound( 35 { 36 queryTokenizer: Bloodhound.tokenizers.whitespace, 37 datumTokenizer: Bloodhound.tokenizers.whitespace, 38 remote: { 39 //note: the prepare function below will add the correct query at the end 40 url: BlocksConstants.RDF_RESOURCES_ENDPOINT + '?' + $.param(params), 41 prepare: function (query, settings) 42 { 43 settings.url = settings.url + encodeURIComponent(query); 44 return settings; 45 }, 46 }, 47 }); 48 49 newPageCopyInput.typeahead( 50 // options 51 { 52 highlight: false, 53 minLength: 1, 54 hint: true, 55 }, 56 // dataset 57 { 58 name: 'allPages', 59 source: newPageEngine, 60 //workaround for bug https://github.com/twitter/typeahead.js/issues/1201#issuecomment-185854471 61 limit: NEW_PAGE_MAX_RESULTS - 1, 62 //sync this with the label field of com.beligum.blocks.fs.index.entries.ResourceIndexEntry 63 display: 'label', 64 templates: { 65 notFound: '<div class="tt-suggestion ' + BlocksConstants.WIDGET_TYPE_RES_SUG_EMPTY_CLASS + '"><p class="' + BlocksConstants.WIDGET_TYPE_RES_SUG_TITLE_CLASS + '">' + BlocksMessages.emptySearchResultsTitle + '</p></div>', 66 // we add title (hover) tags as well because the css will probably chop it off (ellipsis overflow) 67 suggestion: function (data) 68 { 69 return '<div title="' + data.label + ' - ' + data.description + '"><p class="' + BlocksConstants.WIDGET_TYPE_RES_SUG_TITLE_CLASS + '">' + data.label + '</p><p class="' + BlocksConstants.WIDGET_TYPE_RES_SUG_SUBTITLE_CLASS + '">' + data.uri + '</p></div>'; 70 } 71 } 72 }); 73 74 // gets called when a real selection is done 75 newPageCopyInput.bind('typeahead:select', function (ev, suggestion) 76 { 77 var params = {}; 78 params[BlocksConstants.NEW_RESOURCE_PARAM_TASK] = BlocksConstants.NEW_RESOURCE_PARAM_TASK_COPY; 79 // don't enable the advanced panel or the permalink/uri will be able to be changed 80 params[BlocksConstants.NEW_RESOURCE_PARAM_ENABLE_ADVANCED] = false; 81 //note that we want to open the new page here (replacing the "create new page") instead of opening a new tab 82 params[BlocksConstants.NEW_RESOURCE_PARAM_TARGET] = BlocksConstants.NEW_RESOURCE_PARAM_TARGET_SELF; 83 // let's create the new page 'here' 84 params[BlocksConstants.NEW_RESOURCE_PARAM_URI] = window.location.href; 85 // the page we'll be copying 86 params[BlocksConstants.NEW_RESOURCE_PARAM_REFERENCE] = suggestion.uri; 87 88 // decide if we want both pages linked 89 // this is a tricky one and has subtle consequences. For now, we assume both pages need to be linked when we're switching languages, 90 // because it's one of the big original reasons we wrote this dialog window (to link multiple langs together). 91 // The other option (eg. if you want to explicitly link two pages together, even within the same language) is to use the advanced 92 // section of the new resource panel (see MOT site) 93 if (suggestion.language !== BaseMessages.locale) { 94 params[BlocksConstants.NEW_RESOURCE_PARAM_PERMALINK] = suggestion.resource; 95 } 96 97 // let's pre-fill the dialog box with the same label as the page we're copying from 98 params[BlocksConstants.RDF_LABEL_CURIE] = suggestion.label; 99 100 Resources.showNewResourceDialog(params); 101 }); 102 103 /** 104 * Dynamically load a dialog box from the server, based on the data supplied to this method 105 * Note that the params object can contain both will-known properties (like BlocksConstants.NEW_RESOURCE_PARAM_TYPEOF), 106 * but also freely chosen values (like initial values for rdfs:label) 107 */ 108 this.showNewResourceDialog = function (params) 109 { 110 var dialog = Notification.fetchDialogWithAjaxForm(BlocksConstants.GET_NEW_RESOURCE_ENDPOINT, params, 111 function successCallback(form, data, jqxhr, dialog) 112 { 113 // if the successCallback returns false, the dialog won't be closed and reset (keep open during redirect) 114 var retVal = true; 115 116 // all went well, either: 117 // - The resource was initialized and is alive in the flash cache -> redirect or open a new tab to edit/save it 118 // (and close this dialog or it will look like it's still being created) 119 // In this case, the server will return a fake 303 with the redirect location in the header 120 // - the resource was persisted -> close this dialog (or optionally redirect for more editing) 121 // In this case, the server will return with a (custom) current location header and the target html in the data 122 123 // note that if the server responds with a regular 303, the data will hold the target html and we send along the current location in a custom header 124 // this is our fake JSON redirect header 125 var redirectLocation = jqxhr.getResponseHeader(BaseConstants.REDIRECT_LOCATION_HEADER);
126 // this is the header that contains the url that got served (to detect redirects) 127 var targetLocation = jqxhr.getResponseHeader(BaseConstants.TARGET_LOCATION_HEADER); 128 129 if (redirectLocation) { 130 // the means the default action (when no specific target is specified) is to open the link in a new tab 131 // Note that the default @target value of a <form> and the default target of window.open() are not the same! 132 // form default = _self 133 // window.open default = _blank 134 // But initializing it this way, we make it clear _blank is the default action here 135 // because in most cases, leaving the current page intact is the best option. 136 var target = form.attr('target') || '_blank'; 137 window.open(redirectLocation, target); 138 139 // note that we want to keep it open when we'll redirect to another page, to keep it open as long as possible 140 // (otherwise it feels weird that the dialog closes, but the target page is still loading) 141 // except when the new page is openend in a new tab/window 142 if (target !== '_blank') { 143 retVal = false; 144 } 145 } 146 147 // if there's a callback option set, call it 148 // Note that this means the callback can expact the roundtrip to the server to have taken place 149 if (params[BlocksConstants.NEW_RESOURCE_PARAM_CALLBACK]) { 150 params[BlocksConstants.NEW_RESOURCE_PARAM_CALLBACK]({ 151 uri: redirectLocation || targetLocation, 152 // if we didn't redirect, it means the resource was created immediately 153 // note that we can't signal this any other way because the redirect is transparent 154 // and will always result in a code 200 155 created: !redirectLocation, 156 // note: no request headers 157 requestData: form, 158 // note that this will be 201 when the resource was created successfully 159 responseStatus: jqxhr.status, 160 responseHeaders: jqxhr.getAllResponseHeaders(), 161 responseData: data, 162 }); 163 } 164 165 return retVal; 166 }); 167 }; 168 169 // Note the late binding so dynamically created links also work 170 $(document).on("click", "a." + BlocksConstants.NEW_RESOURCE_CLASS, function (event) 171 { 172 // note that .data() converts both data-* attributes to a json object, but also allows us to 173 // set generic values using .data(key, value) -> both will be merged here and returned to showNewResourceDialog() 174 Resources.showNewResourceDialog($(this).data()); 175 }); 176 177 } 178);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.