Disable inaccessible links in Dokuwiki? - hyperlink

Is there any way in Dokuwiki to make links to inaccessible articles (due to insufficient access rights) appear disabled?
I would prefer such a link to be gray and inactive, with perhaps a lock icon, rather than having the user getting an error message when the link is clicked.

This would basically require to disable the cache for each and every page and make your wiki much slower. So I guess the answer is no.

Hmm, something like
global $ID;
if ( auth_quickaclcheck ( $id ) < AUTH_READ ){
...here add .acldisable to $id;
...here add class "disabled" to $id;
}
in core link renderer
and in CSS add .acldisable { color: gray; }

Related

Playwright - not working with zoomed out site

our team decided to zoom out the whole site. So they did this:
This is breaking my PW tests while clicking on the button.
I get this in the inspector:
selector resolved to visible <button id="add-to-cart-btn" data-partid="04-0001" data-…>ADD TO CART</button>
attempting click action
waiting for element to be visible, enabled and stable
element is visible, enabled and stable
scrolling into view if needed
done scrolling
element is outside of the viewport
I found this is an issue in PW https://github.com/microsoft/playwright/issues/2768
My question is: how can I bypass this in the most efficient way?
Is there a way to override a playwright function that sets the initial loading of the page and set my zoom there?
Since if I do it via JavaScript, then I have to do it every time my page reloads, and that can be really tedious and error-prone in the tests.
This is what I have now, but it is really a hack a like solution:
async removeZoomOutClassFromBodyElement() {
await this.#page.evaluate(() => {
const body = document.querySelector('body');
if (body) {
// Removes the class only if it exists on the body tag
body.classList.remove('zoom-out');
} else {
throw Error(ErrorMessage.BODY_NOT_FOUND);
}
});
}
Can you please advise what would be the best approach here?
Thanks!

Intercept dialog from <webview> and read the contents

I use this code to intercept a dialog from a webview but I can not see the content or interact with it:
Element webview= querySelector("#webview");
Map<String,String> map=new Map();
map["src"]=urlWebView+user;
webview.attributes.addAll(map);
querySelector("#webview_cont").style.visibility="visible";
window.addEventListener("dialog",(Event e){ //Use window or webview returns the same result
e.preventDefault();
... //What should I do here ??
} );
Any solution?
Thanks
Edit
Debug:
Open issue: https://code.google.com/p/dart/issues/detail?id=23556
The problem definitely lies with your usage of Dart's Event class.
It simply does not support the extra properties that Chrome is adding to the event: e.dialog, e.messageText, e.messageType.
It does not seem like there is a ready solution for that, at least not in chrome.dart.
Sadly, I don't know Dart well enough to give you a solution. You need to somehow extend that event class, possibly dropping to JS level.
This library, even if abandoned, should give you ideas on how to do that (by catching the JS-level event and stuffing the extra properties in CustomEvent's detail property), though implementing DialogController (which is not JSON-serializable) would be a bit trickier, I guess.

Rendering dynamic scss-files with ajax, rails

As the title suggests, my main objective is to render a dynamic scss(.erb) file after an ajax call.
assets/javascripts/header.js
// onChange of a checkbox, a database boolean field should be toggled via AJAX
$( document ).ready(function() {
$('input[class=collection_cb]').change(function() {
// get the id of the item
var collection_id = $(this).parent().attr("data-collection-id");
// show a loading animation
$("#coll-loading").removeClass("vhidden");
// AJAX call
$.ajax({
type : 'PUT',
url : "/collections/" + collection_id + "/toggle",
success : function() {
// removal of loading animation, a bit delayed, as it would be too fast otherwise
setTimeout(function() {
$("#coll_loading").addClass("vhidden");
}, 300);
},
});
});
});
controller/collections_controller.rb
def toggle
# safety measure to check if the user changes his collection
if current_user.id == Collection.find(params[:id]).user_id
collection = Collection.find(params[:id])
# toggle the collection
collection.toggle! :auto_add_item
else
# redirect the user to error page, alert page
end
render :nothing => true
end
All worked very smooth when I solely toggled the database object.
Now I wanted to add some extra spices and change the CSS of my 50+ li's accordingly to the currently selected collections of the user.
My desired CSS looks like this, it checks li elements if they belong to the collections and give them a border color if so.
ul#list > li[data-collections~='8'][data-collections~='2']
{
border-color: #ff2900;
}
I added this to my controller to generate the []-conditions:
def toggle
# .
# .
# toggle function
# return the currently selected collection ids in the [data-collections]-format
#active_collections = ""
c_ids = current_user.collections.where(:auto_add_item => true).pluck('collections.id')
if c_ids.size != 0
c_ids.each { |id| #active_collections += "[data-collections~='#{id}']" }
end
# this is what gets retrieved
# #active_collections => [data-collections~='8'][data-collections~='2']
end
now I need a way to put those brackets in a scss file that gets generated dynamically.
I tried adding:
respond_to do |format|
format.css
end
to my controller, having the file views/collections/toggle.css.erb
ul#list<%= raw active_collections %> > li<%= raw active_collections %> {
border-color: #ff2900;
}
It didn't work, another way was rendering the css file from my controller, and then passing it to a view as described by Manuel Meurer
Did I mess up with the file names? Like using css instead of scss? Do you have any ideas how I should proceed?
Thanks for your help!
Why dynamic CSS? - reasoning
I know that this should normally happen by adding classes via JavaScript. My reasoning to why I need a dynamic css is that when the user decides to change the selected collections, he does this very concentrated. Something like 4 calls in 3 seconds, then a 5 minutes pause, then 5 calls in 4 seconds. The JavaScript would simply take too long to loop through the 50+ li's after every call.
UPDATE
As it turns out, JavaScript was very fast at handling my "long" list... Thanks y'all for pointing out the errors in my thinking!
In my opinion, the problem you've got isn't to do with CSS; it's to do with how your system works
CSS is loaded static (from the http request), which means when the page is rendered, it will not update if you change the CSS files on the server
JS is client side and is designed to interact with rendered HTML elements (through the DOM). This means that JS by its nature is dynamic, and is why we can use it with technologies like Ajax to change parts of the page
Here's where I think your problem comes in...
Your JS call is not reloading the page, which means the CSS stays static. There is currently no way to reload the CSS and have them render without refreshing (sending an HTTP request). This means that any updating you do with JS will have to include per-loaded CSS
As per the comments to your OP, you should really look at updating the classes of your list elements. If you use something like this it should work instantaneously:
$('li').addClass('new');
Hope this helps?
If I understood your feature correctly, actually all you need can be realized by JavaScript simply, no need for any hack.
Let me organize your feature at first
Given an user visiting the page
When he checks a checkbox
He will see a loading sign which implies this is an interaction with server
When the loading sign stopped
He will see the row(or 'li") he checked has a border which implies his action has been accepted by server
Then comes the solution. For readability I will simplify your loading sign code into named functions instead of real code.
$(document).ready(function() {
$('input[class=collection_cb]').change(function() {
// Use a variable to store parent of current scope for using later
var $parent = $(this).parent();
// get the id of the item
var collection_id = $parent.attr("data-collection-id");
show_loading_sign();
// AJAX call
$.ajax({
type : 'PUT',
url : "/collections/" + collection_id + "/toggle",
success : function() {
// This is the effect you need.
$parent.addClass('green_color_border');
},
error: function() {
$parent.addClass('red_color_border');
},
complete: function() {
close_loading_sign(); /*Close the sign no matter success or error*/
}
});
});
});
Let me know if my understanding of feature is correct and if this could solve the problem.
What if, when the user toggles a collection selection, you use jquery change one class on the ul and then define static styles based on that?
For example, your original markup might be:
ul#list.no_selection
li.collection8.collection2
li.collection1
And your css would have, statically:
ul.collection1 li.collection1,
ul.collection2 li.collection2,
...
ul.collection8 li.collection8 {
border-color: #ff2900;
}
So by default, there wouldn't be a border. But if the user selects collection 8, your jquery would do:
$('ul#list').addClass('collection8')
and voila, border around the li that's in collection8-- without looping over all the lis in javascript and without loading a stylesheet dynamically.
What do you think, would this work in your case?

Google Places Autocomplete with Jquery Mobile not working on mobile/touch device

As title suggests I am building a mobile website with JQuery Mobile (1.3.0) and am trying to implement Google Places Autocomplete (API v3) to aid user input of location data.
The autocomplete functions correctly on desktop device, but not when used on a mobile device (I have only tested on iOS 6).
When used on mobile device the dropdown list of relevant locations do appear, but simply disappear when you press one without loading the selection on the map.
I have looked around and seen some solutions that sight the z-index of
.pac-container
as the culprit (see: http://osdir.com/ml/google-maps-js-api-v3/2012-01/msg00823.html).
I have implemented these fixes but to no avail, and I am not convinced that z-index is the problem because I can see that the selected item does change to it's :hover state/colour when pressed on mobile.
Please if anyone has suggestions I am all ears, need any more details let me know.
Saravanan's answer is a bit overkill. To fix the conflict with FastClick and PAC, add the needsclick class to both the pac-item and all its children.
$(document).on({
'DOMNodeInserted': function() {
$('.pac-item, .pac-item span', this).addClass('needsclick');
}
}, '.pac-container');
Thanks Daniel. But the solution I have given has some performance impact.
I have modifed the FastClick library little bit to accomplish that.
First I have added a param to FastClick constructor, where defaultElCls will be the elements which should not implement fastclick.
function FastClick(layer, defaultElCls) {
'use strict';
var oldOnClick, self = this;
this.defaultElCls = defaultElCls;
Then modify needsClick method:
FastClick.prototype.needsClick = function(target) {
'use strict';
var nodeName = target.nodeName.toLowerCase();
if (nodeName === 'button' || nodeName === 'input') {
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
// Don't send a synthetic click to disabled inputs (issue #62)
if ((this.deviceIsIOS && target.type === 'file') || target.disabled) {
return true;
}
} else if (nodeName === 'label' || nodeName === 'video') {
return true;
}
return ((/\bneedsclick\b/).test(target.className) || (new RegExp(this.defaultElCls).test(target.className)));
};
Then pass pac-item to the FastClick constructor
new FastClick(document.body, "pac-item");
Hope this will be taken care by FastClick library as well :)
I've also encountered this bug, and determined fastclick to be the culprit. I was originally going to go with Devin Smith's answer, but epegzz's warning about MutationEvents being deprecated led me to MutationObservers, and since I haven't seen a fix involving them I thought I'd share my solution.
var observer_config = { attributes: false, childList: true, subTree: false, characterData: false }
var observer = new MutationObserver( function(mutations) {
var self = this;
mutations.forEach(function(mutation){
// look for the container being added to the DOM
var pac_container_added = $(mutation.addedNodes).hasClass('pac-container');
// if it is, begin observing it
if (pac_container_added){
var pac_container = mutation.addedNodes[0];
self.observe(pac_container, observer_config);
}
// look for pac-items being added (as children of pac_container)
// This will not resolve if the observer on pac-container has not been created
var pac_item_added = $(mutation.addedNodes).hasClass('pac-item');
// when pac items are added, add the needsclick class
if (pac_item_added) {
$('.pac-item, .pac-item span').addClass('needsclick')
}
});
});
observer.observe(document.body, observer_config);
It is more complex than I'd like it to be because we can't just add observer.observe('pac_container') in the top level, since its added asynchronously. Luckily, the solution for that problem is also MutationObservers.
We add another observer to pac_container when it is created. That way, it detects the pac-items being added, and when they are, we add the needsclick class.
This is my first time using MutationObservers, so feedback/improvements would be appreciated. As you can see, I used both jquery, but it should be pretty easy to pull it out.
There is a patch for fastclick that makes it work well with google places autocomplete. See This answer :)
After much hair pulling I have found the problem to be the "FastClick" library I added to my project.
As #Saravanan Shanmugam points out in this comment https://stackoverflow.com/a/16932543/1177832
FastClick seems to interfere with autocomplete. Also see above link for the workaround he has added to get the two to play nice.

Setting dialog overlay Jquery

I want to set the overlay of a jQuery dialog to an image, and can't seem to manage the task.
I have other dialogs on the pages that I want to no have the background images, so setting the css for the overlay background won't work as a blanket solution.
I have tried a lot of different methods, and I believe there is a timing issue with the appliction of the jQuery command to set the overlay with css and the actual dialog div's and css getting added to the DOM.
Here is what I have tried so far.
$('#submitUpload').click(function(){
$("#uploadStart").dialog('open');
$(".ui-widget-overlay").css({'background-image': 'url("http://www.mydomain.com/images/ftp-page-bg.gif")','opacity':'1'})
$("#uploadForm").submit();
});
OR
$("#uploadStart").dialog({
autoOpen: false,
width: 400,
modal: true,
closeOnEscape: false,
draggable: false,
resizable: false,
open: function(event, ui) {
$(".ui-dialog-titlebar-close").hide();
$(".ui-widget-overlay").css({'background-image': 'url("http://www.mydomain.com/images/ftp-page-bg.gif")','opacity':'1'})
}
});
I have also tried using the dialogClass method on the dialog code with no success.
With both the absolute url and the relative, and the url in quotes or with no quotes.
The image exists in the directory.
Anyone have any ideas on how to get jQuery to apply with the correct timing to display the image as the overlay?
Thanks!
Update
The dialog class designation will allow you to set classes for the overal dialog. I was actually looking to just tap into the specific ui-widget-overlay class and over-ride the background image there. I found that trying to override the background using the dialogClass worked for overriding the background of the dialog, not the overlay background.
When the dialog is added to the DOM, jQuery loads it's div's right before the body tag.
I found a solution, being that in the open method for the dialog, I used
$(".ui-widget-overlay").addClass('artFTP');
to add a class
.artFTP{background-image: url(../../images/ftp-page-bg.gif); opacity:1;}
and made sure it was the last class in the file that would overwrite the overlay background image.
I hope this helps someone.
Thanks and +1 to jjross, your answer got me to jump back into the jQuery docs.
If anyone has a better solution, please post. I would be happy to see it. I think there might be a way to use CSS to accomplish the task, but (for the life of me) couldn't figure it out.
You should be able to add the class to the div in your HTML code prior to jquery being called on it. In my testing, this automatically added that class to the dialog when it was created.
In the new class, you should be able to specify a background image.
For example:
calling:
$("#dialog").dialog();
on
<div id="dialog" class="thisClass" title="Edit Case Status">
<div>some stuff</div>
</div>
causes the dialog to be created with the
"thisClass" class.
as an alternative option, it looks like the dialog has a "dialogClass" method. It will let you add your own class to the dialog (in that class, you can define the background). From the docs:
The specified class name(s) will be added to the dialog, for additional theming.
Code examples
Initialize a dialog with the dialogClass option specified.
$( ".selector" ).dialog({ dialogClass: 'alert' });
Get or set the dialogClass option, after init.
//getter
var dialogClass = $( ".selector" ).dialog( "option", "dialogClass" );
//setter
$( ".selector" ).dialog( "option", "dialogClass", 'alert' );
I encountered the same problem and found In this case your question. I didn't find any solution that could satisfy me, so I did something on my own.
First, let me introduce my problem.
I have a page, where I have two kinds of dialogs. Dialogs with video and dialogs with message (like alert, confirmation, error etc.). As we know, we can set a different class for a dialog, but we can't set class for different overlay. So question was, how to set a different behavior for different overlays?
So I dig, I dig deeper than Dwarves in Moria into jQuery ui code itself. I found out, that actualy there is an unique overlay for each dialog. And it is created in "private" function _createOverlay which is not accessible. In fact, I found function via jquery ui namespace as $.ui.dialog.prototype._createOverlay. So I was able to make a small extension with logic based on class:
(function() {
// memorize old function
var originFn = $.ui.dialog.prototype._createOverlay;
// make new function
$.ui.dialog.prototype._createOverlay = function() {
originFn.call(this); // call old one
// write your own extension code there
if (this.options["dialogClass"] === "video-dialog") {
var overlay = this.overlay; // memorize overlay (it is in old function call as this.overlay)
var that = this; // just cause bind is event
// my own extenstion, when you click anywhere on overlay, dialog is closed + I change css
overlay.bind('click', function() {
that.close(); // it is same like element.dialog('close');
}).css({
"background": "none",
"background-image": "url(\'files/main-page/profile1.png\')" // this didnt work for you, but works for me... maybe I have newer version of jQuery.UI
// anyway, once you have overlay as variable, Im sure you will be able to change its css
});
}
};
})();
I hope this will help others :)

Resources