How can I prefill links with http in a Quill editor? - wysiwyg

When adding links with the Quill editor I must include the protocol or the link is treated as a relative link.
When someone clicks to add a link I would like to have the field prepopulate with http:// so when a user types google.com it will create a link to http://google.com instead of http://myapp.net/something/google.com.
Stack overflow does this...

The above solution won't work when you try to save an existing link. Also, it ignores other protocols such as (mailto, tel, https)
Here is a better solution:
let Link = window.Quill.import('formats/link');
class CustomLink extends Link {
static sanitize(url) {
let value = super.sanitize(url);
if (value) {
for (let i = 0; i < this.PROTOCOL_WHITELIST.length; i++)
if(value.startsWith(this.PROTOCOL_WHITELIST[i]))
return value;
return `http://${value}`
}
return value;
}
}
Quill.register(CustomLink);

You can extend the link format with custom logic:
var Link = Quill.import('formats/link');
class MyLink extends Link {
static create(value) {
let node = super.create(value);
value = this.sanitize(value);
if(!value.startsWith("http")) {
value = "http://" + value;
}
node.setAttribute('href', value);
return node;
}
}
Quill.register(MyLink);

Related

Protractor: How do I create a function that receives an HTML element as a parameter?

I'm new to Protractor.
I'm trying to select a button based on the button title. I want to make this into a function, and pass the button title in as a parameter.
This is the hard-coded version which works:
it('I click on a button based on the button title', async function() {
let button = element(by.css('button[title=example_button_title]'));
await button.click();
});
I created a global variable and a function to try and replace this, where 'buttonTitle' is the parameter I'm passing into the function:
Variable:
let dynamicButton = buttonTitle => { return element(by.css("'button[title=" + buttonTitle + "]'")) };
Function:
this.selectDynamicButton = async function(buttonTitle) {
await browser.waitForAngularEnabled(false);
await dynamicButton(buttonTitle).click();
};
When I try this I get the following error:
Failed: invalid selector: An invalid or illegal selector was specified
Apologies if there appear to be basic errors here, I am still learning. I appreciate any help that anyone can give me. Thanks.
You can add a custom locator using protractors addLocator functionality. (this is actually a very similar use case to the example listed in the link)
This would look like the following:
onPrepare: function () {
by.addLocator('buttonTitle', function (titleText, opt_parentElement) {
// This function will be serialized as a string and will execute in the
// browser. The first argument is the text for the button. The second
// argument is the parent element, if any.
const using = opt_parentElement || document;
const matchingButtons = using.querySelectorAll(`button[title="${titleText}"]`);
let result = undefined;
if (matchingButtons.length === 0) {
result = null;
} else if (matchingButtons.length === 1) {
result = matchingButtons[0];
} else {
result = matchingButtons;
}
return result;
});
}
This is called like
const firstMatchingButton = element(by.buttonTitle('example_button_title'));
const allMatchingButtons = element.all(by.buttonTitle('example_button_title'));
I had to edit this code before posting so let me know if this does not work. My work here is largely based off this previous answer
let dynamicButton = buttonTitle => { return element(by.css('button[title=${buttonTitle} ]')) };
Use template literals instead of string concatenation with +.
Protractor already has a built in locator which allows you to get a button using the text. I think you are looking at something like that. See the element(by.buttonText('text of button')) locator.
For more reference see here.

In AEM how to add a new node called “listeners” in the component dialog ,without using dialog.xml file

Actaully i am using "before submit" listener to do some validation for my selection box
I have reffered the following link:
https://helpx.adobe.com/experience-manager/using/classic_dialog_validation.html.
But "before submit" method calling only when i place ,
dialog listener in the dialog root level only.
how to place dialog listener in dialog root level(I checked in my project there is no dialog.xml file ,they using only java code to construct component dialog).
Can anyone please help me in this ?enter image description here
Dialog property construction code :
#DialogField(name ="./validateProgram",
fieldLabel = "Validate Program",
fieldDescription = "(synchronized)",
additionalProperties = {
#Property(renderIn = Property.RenderValue.TOUCH,
name = "validation",
value = "validation-program")
},
listeners = {
#Listener(name ="beforesubmit",
value = "function(dialog){" +
"return programValidation.beforeSubmit(dialog);"+
"}")
})
#Selection(
type ="select",
optionsProvider = " ",
dataSource = "/resourcetype/data")
public final String validateProgram;
Java Script code:
window.onload = function() {
programValidation.init();
};
var programValidation= programValidation|| (function($) {
function initialize() {
};
function validate() {
alert("inside validate method");
var res = true;
return res;
};
return {
beforeSubmit: validate,
init: initialize
}
})(jQuery);
You are using the cq component maven plugin this a very vital piece of information to get your question answered.
I have not used this plugin before, but in your case, I assume you are looking for the Listener annotation where you can set the name as beforesubmit and the value as function(){alert(1)}
you'll probably have to set the annotation on a local variable similar to how you would annotate a dialog field '#DialogField', find more docs in the plugin's usage page here: http://code.digitalatolson.com/cq-component-maven-plugin/usage.html
Hope this helps.
Thanks for your support. Found the following way to solve the issue .
I added ValidateFields method from within the 2 listeners (FIELD_LISTENER_LOAD_CONTENT and FIELD_LISTENER_SELECTION_CHANGED)
function ValidateFields(dialog) {
dialog.on("beforesubmit", function(e) {
if(<condtion failed>)
CQ.Ext.Msg.alert(CQ.I18n.getMessage("Error"), CQ.I18n.getMessage("<error message>"));
return false;
} else {
return true;
}
}, this);
}

Make Webview's auto links visible

A Webview will display links in the content HTML as having blue underlines. So if you have something in the HTML like
blah blah
... it is clearly visible as a link.
The Webview also allows you to click on phone numbers and addresses (even if those are just text in the HTML, not links) to launch the Dialer or Maps.
How can one get Webview to display those (Linkify, probably) links with underlines etc? It's easy enough in a TextView since one can get the spans from a TextView and style them, but Webview doesn't expose any way to retrieve that data... at least not that I can see looking through the docs.
Here is some JS code which can be injected to linkify phone numbers, emails and urls:
function linkify() {
linkifyTexts(linkifyPhoneNumbers);
linkifyTexts(linkifyEmails);
linkifyTexts(linkifyWebAddresses1);
linkifyTexts(linkifyWebAddresses2);
}
function linkifyPhoneNumbers(text) {
text = text.replace(/\b\+?[0-9\-]+\*?\b/g, '$&');
return text;
}
function linkifyEmails(text) {
text = text.replace(/(\w+#[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim, '$1');
return text;
}
function linkifyWebAddresses1(text) {
text = text.replace(/(\b(https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/gim, '$1');
return text;
}
function linkifyWebAddresses2(text) {
text = text.replace(/(^|[^\/])(www\.[\S]+(\b|$))/gim, '$1$2');
return text;
}
var linkifyTexts = function(replaceFunc)
{
var tNodes = [];
getTextNodes(document.body,false,tNodes,false);
var l = tNodes.length;
while(l--)
{
wrapNode(tNodes[l], replaceFunc);
}
}
function getTextNodes(node, includeWhitespaceNodes,textNodes,match) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || !/^\s*$/.test(node.nodeValue)) {
if(match){
if(match.test(node.nodeValue))
textNodes.push(node);
}
else {
textNodes.push(node);
}
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
var subnode = node.childNodes[i];
if (subnode.nodeName != "A") {
getTextNodes(subnode,includeWhitespaceNodes,textNodes,match);
}
}
}
}
function wrapNode(n, replaceFunc) {
var temp = document.createElement('div');
if(n.data)
temp.innerHTML = replaceFunc(n.data);
else{
//whatever
}
while (temp.firstChild) {
n.parentNode.insertBefore(temp.firstChild,n);
}
n.parentNode.removeChild(n);
}
Given this:
http://code.google.com/p/android/issues/detail?id=742
it still doesn't seem to be a way to do this from Java directly. One thing that might work is to write some JavaScript code and run it after page is loaded, e.g. as given here:
In Android Webview, am I able to modify a webpage's DOM?
Here's an example of a similar thing:
Disabling links in android WebView
where the idea is to disable links. You may be able to use a similar approach to add some CSS, including underlining. A couple of other SOqs / links that might help:
Android: Injecting Javascript into a Webview outside the onPageFinished Event
Android: Injecting Javascript into a Webview outside the onPageFinished Event
http://iphoneincubator.com/blog/windows-views/how-to-inject-javascript-functions-into-a-uiwebview
Injecting Javascript into a Webview outside the onPageFinished Event (Using DatePicker to set a date on an input of a WebView)
Hope this helps.

Jquery in Custom HTML Helper Extensions to pick value from the form

I have used this custom Helper in My Razor View.
#Html.Link("OpenewWindow", Constants.Value, new { k = Constants.k, Staff_ID = LoginHelper.GetLoggedInUser() }, new { id = "mytag", target="_blank" })
When I Click on this link it opens me a new window with the Querystrings ConstantValue/Constants?=someValue&Staff_ID=UserLoggedName.
I want to pick the radio button selected value on the form and pass the checked value in QueryString.
So where can I use Jquery function in my custom Helper method to pick the value from the form.
The Custom Helper method takes this kind of aurguments.
public static IHtmlString Link(this HtmlHelper htmlHelper, string linkText, string baseUrl, object query, object htmlAttributes).
You could use javascript to do that. For example you could subscribe to the click event of the link and then open a popup window by appending the new query string parameter:
$(function() {
$('#id_of_link').click(function() {
var url = this.href;
if (url.indexOf('?') > -1) {
url += '&';
} else {
url += '?';
}
// get the value of the radio button
var value = $(':radio[name="name_of_your_radio_groups"]:checked').val();
url += url + 'radiovalue=' + encodeURIComponent(value);
window.open(url, 'newwindow');
// cancel the default action
return false;
});
});
If you don't need to use javascript then a cleaner approach is to use a form instead of a link. This way the value of the selected radio button will automatically be sent.

how prevent duplicate code in wicket

Sorry my english is bad
I have two class profile and EditProfile
in both class i have
protected void addContent(PageParameters pageParameters) {
final String email = pageParameters.get(ListUser.USER_EMAIL).toString();
final User loggedUser = getLoggedUser();
if (email == null) {
redirectToInterceptPage(new ErrorPage404(null));
return;
}
User userByEmail = userService.findByEmail(email);
if (userByEmail == null) {
redirectToInterceptPage(new ForbiddenPage403(null));
return;
}
final UserDetachableModel user = new UserDetachableModel(userByEmail);
// If the user is not active, there is no need to edit your profile.
if (!user.getObject().isActive()) {
redirectToInterceptPage(new ErrorPage404(null));
return;
}
// Only admins can see the profile of other users.
if (!loggedUser.getUserRole().equals(UserRole.ADMIN) && !loggedUser.getEmail().equalsIgnoreCase(email)) {
redirectToInterceptPage(new ForbiddenPage403(null));
return;
}
......PROCESS TO SEE PROFILE OR EDIT PROFILE........
}
I use a CustomMountedPage that i use to hide the serial number of wicket.
Example http://HOST/Page/subPage?ID&PARAMS to see http://HOST/Page/subPage?PARAMS and access to another profile
How prevent duplicate code!!
You can use Panels. They have their own markup file like a normal page but you can use them in any other Wicket-Page as a component.
Have a look at this page to see how to use panels correctly.