My first ExtendScript... and it doesn't work - adobe

I am developing a script for Adobe Bridge CS6. For the moment, all I want to do is to access the size (width and height) of a thumbnail that the user has selected and show it, either on a popup or on the console. Here is my script:
function TestBridge() {
this.requiredContext = "\tAdobe Bridge must be running.\n\tExecute against Bridge as the Target.\n";
}
TestBridge.prototype.run = function() {
if(!this.canRun())
{
return false;
}
var selectedThumbnails = app.document.getSelection();
if (selectedThumbnails.length > 0) {
$.writeln("MEEEEEPT");
var thumb = selectedThumbnails[0];
var x = thumb.core.preview.preview.width;
var y = thumb.core.preview.preview.height;
//alert('MEEEEEPT: x = ' + x + ', y = ' + y);
$.writeln("MEEEEEPT: x = " + x + ", y = " + y);
return true;
}
$.writeln("MOOO");
return false;
}
TestBridge.prototype.canRun = function()
{
// Must be running in Bridge & have a selection
if( (BridgeTalk.appName == "bridge") && (app.document.selectionLength == 1)) {
return true;
}
// Fail if these preconditions are not met.
// Bridge must be running,
// There must be a selection.
$.writeln("ERROR:: Cannot run.");
$.writeln(this.requiredContext);
return false;
}
The only problem is that... well, it doesnt work. I open it on ExtendScript Toolkit, set the target to Bridge CS6, hit "Run"... and all that happens is that the console says "Result: canRun()".
Looking at other code samples from Adobe, I see that the structure of their scripts is pretty much the same as mine, so I don't really know what I'm doing wrong.
Edit: what I needed was to add in the end a line to call the function, like so:
new.TestBridge.run();
Silly, silly mistake.

Related

Restrict typeform to single submission on Wordpress post

Have a simple typeform embedded into a post in Wordpress. Nothing fancy at all. Embed code pulled direct from Typeform.
However, people can submit multiple times. ie. One person could theoretically do it 100 times.
Typeform have advised a cookie will solve this, and restrict a user to a single submission - but really do not know where to begin there. Is there a simple, quick fix that could do such a thing? Any ideas completely welcome!
One of the solutions could be only showing the embedded typeform if the cookie does not exist.
not really sure how you would do this in Wordpress.
But the logic is:
const embedElement = document.querySelector('.target-dom-node')
const displayed = getCookie("displayed_typeform");
if (displayed){
embedElement.innerHTML="<h2>Typeform already displayed once.</h2>"
} else if(!displayed && displayed === "") {
setCookie("displayed_typeform", true, 365);
showEmbed();
}
setCookie and getCookie are two functions that deal with cookie management
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
You can find a complete project that demonstrates this feature here.

Using Page Hits for Segmentation in Adobe CQ5

I am trying to set up personalised content in CQ5 using segmentation. When I use the out of the box "Page Hits" option it doesn't work. Is there some extra configuration I have to do to use Page Hits?
I've set up two segments applied to two teaser pages. For the first one I've used
number of page hits is less than 4.
For the second I've used number of page hist is greater than 3.
Note, the teasers show up when I use Referral Keywords to test so I think the rest of the configuration is correct.
Can anyone give some advice about how to get the Page Hits segmentations to work?
Just in case anyone else has this same problem, I solved it by using a session store and set a cookie on the users browser to record how many times they had been to a particular page. Using that, I was able to configure my segments and personalise areas of the page based on number of visits the user had made to that page.
Code for the session store:
//Create the session store
if (!CQ_Analytics.MyStore) {
CQ_Analytics.MyStore = new CQ_Analytics.PersistedSessionStore();
CQ_Analytics.MyStore.STOREKEY = "MYSTORE";
CQ_Analytics.MyStore.STORENAME = "myclientstore";
CQ_Analytics.MyStore.data={};
CQ_Analytics.MyStore.findPageName = function(){
var locationName = location.pathname;
var n = location.pathname.indexOf("html");
if(n !== -1){
locationName = locationName.split('.')[0];
}
return locationName.split("/").slice(-1);
}
CQ_Analytics.MyStore.title = CQ_Analytics.MyStore.findPageName() + "-pageviews";
CQ_Analytics.MyStore.loadData = function(pageViewed) {
CQ_Analytics.MyStore.data = {"pageviewed":pageViewed};
}
CQ_Analytics.MyStore.getCookie = function(cname) {
console.log("getting the cookie");
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) == 0){
console.log("return value for cookie is " + c.substring(name.length,c.length) );
return c.substring(name.length,c.length);
}
}
return "";
}
CQ_Analytics.MyStore.setCookie = function(cname, cvalue, exdays) {
console.log("setting the cookie");
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
CQ_Analytics.MyStore.checkCookie = function() {
console.log("checking for cookie");
var pViewd = CQ_Analytics.MyStore.getCookie(CQ_Analytics.MyStore.title);
if (pViewd != "") {
console.log("cookie is found and Viewed is " + pViewd);
pViewd = parseInt(pViewd) + 1;
CQ_Analytics.MyStore.setCookie(CQ_Analytics.MyStore.title, pViewd, 365);
CQ_Analytics.MyStore.loadData(pViewd.toString());
} else {
if (pViewd === "" || pViewd === null) {
console.log("cookie not found");
CQ_Analytics.MyStore.setCookie(CQ_Analytics.MyStore.title, "1", 365);
CQ_Analytics.MyStore.loadData("1");
}
}
}
CQ_Analytics.MyStore.checkCookie();
}
//register the session store
if (CQ_Analytics.CCM){
CQ_Analytics.CCM.register(CQ_Analytics.MyStore)
}
The most useful documentation I found was this: https://docs.adobe.com/docs/en/cq/5-6-1/developing/client_context_detail.html#par_title_34

TypeError: window.tinyMCE.execInstanceCommand is not a function

I can't add any shortcode in my wordpress editor. it shows - Uncaught TypeError: Object [object Object] has no method 'execInstanceCommand' . plesase help me to solve this.
the code(tinymce.js)
function init() {
tinyMCEPopup.resizeToInnerSize();
}
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
function tjshortcodesubmit() {
var tagtext;
var tj_shortcode = document.getElementById('tjshortcode_panel');
// who is active ?
if (tj_shortcode.className.indexOf('current') != -1) {
var tj_shortcodeid = document.getElementById('tjshortcode_tag').value;
switch(tj_shortcodeid)
{
case 0:
tinyMCEPopup.close();
break;
case "button":
tagtext = "["+ tj_shortcodeid + " url=\"#\" style=\"white\" size=\"small\"] Button text [/" + tj_shortcodeid + "]";
break;
case "alert":
tagtext = "["+ tj_shortcodeid + " style=\"white\"] Alert text [/" + tj_shortcodeid + "]";
break;
case "toggle":
tagtext = "["+ tj_shortcodeid + " title=\"Title goes here\"] Content here [/" + tj_shortcodeid + "]";
break;
case "tabs":
tagtext="["+tj_shortcodeid + " tab1=\"Tab 1 Title\" tab2=\"Tab 2 Title\" tab3=\"Tab 3 Title\"] [tab]Insert tab 1 content here[/tab] [tab]Insert tab 2 content here[/tab] [tab]Insert tab 3 content here[/tab] [/" + tj_shortcodeid + "]";
break;
default:
tagtext="["+tj_shortcodeid + "] Insert you content here [/" + tj_shortcodeid + "]";
}
}
if(window.tinyMCE) {
//TODO: For QTranslate we should use here 'qtrans_textarea_content' instead 'content'
window.tinyMCE.execInstanceCommand('content', 'mceInsertContent', false, tagtext);
//Peforms a clean up of the current editor HTML.
//tinyMCEPopup.editor.execCommand('mceCleanup');
//Repaints the editor. Sometimes the browser has graphic glitches.
tinyMCEPopup.editor.execCommand('mceRepaint');
tinyMCEPopup.close();
}
return;
}
I had the same problem. Change your code to this and it should work:
if(window.tinyMCE) {
/* get the TinyMCE version to account for API diffs */
var tmce_ver=window.tinyMCE.majorVersion;
if (tmce_ver>="4") {
window.tinyMCE.execCommand('mceInsertContent', false, tagtext);
} else {
window.tinyMCE.execInstanceCommand('content', 'mceInsertContent', false, tagtext);
}
tinyMCEPopup.editor.execCommand('mceRepaint');
tinyMCEPopup.close();
}
return;
}
Note: since .js files are cached, you'll need to do a hard refresh to get this to work. If you are still seeing the same console errors, that would likely be the cause.
Scott B's answer is partially innacurate.
The point of execInstanceCommand in TinyMCE version 3 was to execute a command on a specific instance of TinyMCE in the document. Calling execCommand without specifying an instance will either use the focused instance or the first instance in the document, if none is currently focused.
To specify the instance you would like to execute your command on in TinyMCE version 4, call execCommand on the desired editor instance like so:
tinyMCE.get(editorId).execCommand(...);

Switching sprites of a object in different rooms

I am creating a character selection which changes the sprites of the main character.
To do this I have an arrow object which the user clicks to change the sprite of the main character.
global.Mario = true;
global.PrincessPeach = false;
global.Luigi = false;
global.Bowser = false;
if (mouse_check_button_pressed(mb_left)) {
if (global.Mario = true) {
Mario = false;
PrincessPeach= true;
}
if (global.PrincessPeach= true) {
PrincessPeach = true;
Mario = false;
}
if (global.Luigi = true) {
Luigi = false;
Bowser = true;
}
if (global.Bowser = true) {
Bowser = false;
Mario = true;
}
}
Then, on my main character I have a created an event executing code similar to the following:
if (global.Mario = true) {
sprite_index = Mario_NotJumping;
}
if (global.Luigi = true) {
sprite_index = Luigispr;
}
However, when I run my game to test it out, I get the following error:
FATAL ERROR in
action number 1
of Create Event
for object Mario_selection:
Push :: Execution Error - Variable Get -5.Mario(100000, -1)
at gml_Object_Mario_selection_Create_0 (line 1) - if (global.Mario = true) {
The object Mario_selection has the exact create event and same code as the main character. To display changes to the user.
If anyone could help me out, I am fairly new to GameMaker so I have a feeling I'm just misunderstanding global variables.
It looks like the var global.Mario, has not been declared. In the arrow objects create event put,
global.Mario = true;
global.PrincessPeach = false;
global.Luigi = false;
global.Bowser = false;
If i were you, i would save the chosen "image" of the user in 1 simple variable.
Add a few constants;
PLAYER_MARIO = 0;
PLAYER_PEACH = 1;
PLAYER_LUIGI = 2;
PLAYER_BOWSER = 3;
Then you can use those constants and save them in a global variable;
global.player_image = PLAYER_LUIGI;
Then you can use those in your objects like so;
switch (global.player_image) {
case PLAYER_MARIO:
sprite_index = Mario_NotJumping;
break;
case PLAYER_PEACH:
sprite_index = Peach_NotJumping;
break;
case PLAYER_LUIGI:
sprite_index = Luigi_NotJumping;
break;
case PLAYER_BOWSER:
sprite_index = Bowser_NotJumping;
break;
}
The specific error you were getting was because the global variable was not defined at the time of use.
A better method by the way, would be something like this - saving all sprite handles into specific variables, then using those.
Define some constants for readability;
P_LEFT = 0;
P_RIGHT = 1;
P_JUMP = 2;
Then whenever a player switches its character;
//When the user switches to peach;
global.player_sprite[P_LEFT] = spr_Peach_Left;
global.player_sprite[P_RIGHT] = spr_Peach_Right;
global.player_sprite[P_JUMPING] = spr_Peach_Jumping;
And overwrite;
//When the user switches to Luigi;
global.player_sprite[P_LEFT] = spr_Luigi_Left;
global.player_sprite[P_RIGHT] = spr_Luigi_Right;
global.player_sprite[P_JUMPING] = spr_Luigi_Jumping;
Then you can code all code like this;
if (jumping) {
sprite_index = global.player_sprite[P_JUMPING];
} else {
sprite_index = global.player_sprite[P_LEFT];
}
Do you understand what i mean? This way you won't need the switch statements everywhere, and just store the chosen sprites in 1 single array at the beginning of the game.
You can then code the game without having to check what player image the player chose.
Also, always define global variables at the beginning of the game. Global variables will always exist in the game, in every room, at any given moment.
You should use var mario=true; instead.

Show static non-clickable heading in AutoCompleteExtender list

I have an AutoCompleteExtender from the Ajax Control Toolkit. I need to have a heading in the dropdown list that shows how many items found, but it should not be selectable as an item.
I have tried this using jQuery, but even when I just add as a div, it is still selected as an item into the text box when I click on it:
function clientPopulated(sender, e) {
var completionList = $find("AutoCompleteEx").get_completionList();
var completionListNodes = completionList.childNodes;
for (i = 0; i < completionListNodes.length; i++) {
completionListNodes[i].title = completionListNodes[i]._value.split(':')[2];
}
var resultsHeader;
if(completionListNodes.length==1000)
resultsHeader = 'Max count of 1000 reached.<br/>Please refine your search.';
else if(completionListNodes.length>0)
resultsHeader = completionListNodes.length + ' hits.';
else
resultsHeader = msg_NoObjectsFound ;
jQuery(completionListNodes[0]).before('<div>' + resultsHeader + '</div>');
}
Add OnClientItemSelected and OnClientShowing events handlers and try script below:
function itemSelected(sender, args) {
if (args.get_value() == null) {
sender._element.value = "";
}
}
function clientShowing() {
var extender = $find("AutoCompleteEx");
var optionsCount = extender.get_completionSetCount();
var message = "";
if (optionsCount == 1000) {
message = 'Max count of 1000 reached.<br/>Please refine your search.';
}
else if (optionsCount > 0) {
message = optionsCount + " hits."
}
else {
message = "oops."
}
jQuery(extender.get_completionList()).prepend("<li style='background-color:#ccc !important;'>" + message + "</li>");
}
Added:
you even can do this without OnClientItemSelected handler:
function clientShowing() {
var extender = $find("AutoCompleteEx");
var oldSetText = extender._setText;
extender._setText = function (item) {
if (item.rel == "header") {
extender._element.value = "";
return;
}
oldSetText.call(extender, item);
};
var optionsCount = extender.get_completionSetCount();
var message = "";
if (optionsCount == 1000) {
message = 'Max count of 1000 reached.<br/>Please refine your search.';
}
else if (optionsCount > 0) {
message = optionsCount + " hits."
}
else {
message = "oops."
}
jQuery(extender.get_completionList()).prepend("<li rel='header' style='background-color:#ccc !important;'>" + message + "</li>");
}
We can give a better answer if you post the output html of your autocomplete control. Anyway if its a dropdown control;
jQuery(completionListNodes[0]).before('
<option value="-99" disabled="disabled">your message here</option>'
);
The answer by Yuriy helped me in solving it so I give him credit although his sollution needed some changes to work.
First of all, the clientShowing event (mapped by setting OnClientShowing = "clientShowing" in the AutoExtender control) is executed on initialization. Here we override the _setText method to make sure nothing happens when clicking on the header element. I have used the overriding idea from Yuriy's answer that really did the trick for me. I only changed to check on css class instead of a ref attribute value.
function clientShowing(sender, e) {
var extender = sender;
var oldSetText = extender._setText;
extender._setText = function (item) {
if (jQuery(item).hasClass('listHeader')) {
// Do nothing. The original version sets the item text to the search
// textbox here, but I just want to keep the current search text.
return;
}
// Call the original version of the _setText method
oldSetText.call(extender, item);
};
}
So then we need to add the header element to the top of the list. This has to be done in the clientPopulated event (mapped by setting OnClientPopulated = "clientPopulated" in the AutoExtender control). This event is executed each time the search results have been finished populated, so here we have the correct search count available.
function clientPopulated(sender, e) {
var extender = sender;
var completionList = extender.get_completionList();
var completionListCount = completionList.childNodes.length;
var maxCount = extender.get_completionSetCount();
var resultsHeader;
if(completionListCount == maxCount)
resultsHeader = 'Max count of ' + maxCount + ' reached.<br/>'
+ 'Please refine your search.';
else if(completionListCount > 0)
resultsHeader = completionListCount + ' hits.';
else
resultsHeader = 'No objects found';
jQuery(completionList).prepend(
'<li class="listHeader">' + resultsHeader + '</li>');
}
I have also created a new css class to display this properly. I have used !important to make sure this overrides the mousover style added from the AutoExtender control.
.listHeader
{
background-color : #fafffa !important;
color : #061069 !important;
cursor : default !important;
}

Resources