In a polymer control,'my-grid', I'm trying to add style via the below code:
var styleElement = document.createElement('style', 'custom-style');
styleElement.innerHTML = cssText;
Polymer.StyleDefaults.addStyle(styleElement);
Here, the cssText can be string like
.oc-col-id-0{
flex-basis: var(--oc-col-id-0-flex-basis);
-webkit-flex-basis: var(--oc-col-id-0-flex-basis);
}
.oc-col-id-1{
flex-basis: var(--oc-col-id-1-flex-basis);
-webkit-flex-basis: var(--oc-col-id-1-flex-basis);
}
Without this custom variables, I can append the styleElement by
this.$.gridContainer.appendChild(styleElement);
But however, since there are custom variables, I'm not sure how to fix this issue.
After the element is attached, I can't change the --oc-col-id-0-flex-basis value via
this.customStyle['--oc-col-id-0-flex-basis'] = maxWidth + "px";
this.updateStyles();
It looks that the style variables are not applied to the element.
I'm not sure if there is any way to dynamically add/modify the style of the element. I'm not sure if I'm on the right track.
This is what I do in the end to inject the style class dynamically. It solved my problem so far.
var style = this._styles[0];
var text = style.textContent;
var cssText = "";
for (var id of ids)
{
var classStyle = ".col-id-" + id;
var variableProperty = "--col-id-" + id + "-flex-basis";
if (text.indexOf(classStyle) == -1)
{
cssText += classStyle + "{ flex-basis: var(" + variableProperty + ", auto); -webkit-flex-basis: var(" + variableProperty + ", auto);} ";
}
if (this._ownStylePropertyNames.indexOf(variableProperty) == -1)
{
this._ownStylePropertyNames.push(variableProperty);
}
}
if (cssText.length > 0)
{
style.textContent += " " + cssText;
style.__cssRules = null; //trick for rulesForStyle method in Polymer.html
}
Related
I continue my work on collaborative sketch tool and trying to add retina devices support. Currently i have following behavior if user creating drawing on ipad air:
small movie
Here is my code:
this.getZoomLevel = function (height) {
if (height > 1024) {
return 1024 / height;
} else {
return height / 1024;
}
};
this.calculateCanvasSize = function(pHeight, pWidth) {
var result = {
height: 0,
width: 0
};
while (result.width < pWidth - 1 && result.height < pHeight - 1) {
result.height = result.height + 1;
result.width = result.height * 4 / 3;
}
return result;
};
this.initCanvas = function () {
try {
var parent = document.getElementsByClassName('komaso-canvas-container')[0];
var canvasSize = this.calculateCanvasSize(parent.clientHeight, parent.clientWidth);
var canvasHtml = "<div id='wrapper-" + this.Id + "' class='whiteboard-canvas-wrapper' data-ng-show='CurrentPage.Id==" + this.Id + "'><canvas width='" + canvasSize.width + "' height='" + canvasSize.height + "' id='whiteboard-" + this.Id + "' class='whiteboard'><p>Your brower does not support Canvas/p></canvas></div>";
$(parent).append($compile(canvasHtml)(scope));
this.Canvaso = document.getElementById(this.HtmlId);
if (!this.Canvaso) {
console.log('Error: Cannot find the imageView canvas element!');
return;
}
if (!this.Canvaso.getContext) {
console.log('Error: no canvas.getContext!');
return;
}
this.FabricCanvas = new fabric.Canvas(this.HtmlId, { selectionColor: 'transparent' });
this.FabricCanvas.setWidth(canvasSize.width);
this.FabricCanvas.setHeight(canvasSize.height);
fabric.Object.prototype.transparentCorners = false;
this.FabricCanvas.on('mouse:down', this.onMouseDown);
this.FabricCanvas.on('mouse:up', this.onMouseUp);
this.FabricCanvas.on('mouse:move', this.onMouseMove);
this.FabricCanvas.on('object:added', this.onObjectAdded);
this.FabricCanvas.on('text:editing:exited', self.onTextObjectEdited);
if (window.devicePixelRatio !== 1) {
var c = this.FabricCanvas.getElement();
var w = c.width, h = c.height;
c.setAttribute('width', w * window.devicePixelRatio);
c.setAttribute('height', h * window.devicePixelRatio);
$(c).width(canvasSize.width);
$(c).height(canvasSize.height);
c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
}
this.FabricCanvas.setZoom(this.getZoomLevel(this.Canvaso.height));
this.ToggleTool(self.CurrentTool.ToolName);
this.WhiteboardInitiated = true;
} catch (e) {
console.log(e);
}
};
getZoomLevel returns value to pass into SetZoom method of fabric js canvas object. We decided to have all clients canvas aspects are 4:3 and default dimension is 1024*768. So based on this dimensions we calculation zoom factor.
calculateCanvasSize - returns width and height for canvas according to 4:3 rule.
If you have any idea about how to fix this wrong behavior then post your comment please. Thank you in advance!
I would suggest you yo update to a retina enabled version of fabricjs (grab 1.6.2).
If, for any reason you can't, i think the problem is here:
if (window.devicePixelRatio !== 1) {
var c = this.FabricCanvas.getElement();
...
c.getContext('2d').scale(window.devicePixelRatio, window.devicePixelRatio);
}
getContext return a new context. This is not the context where fabric is gonna render later. If you want to have retina enabled lowerCanvas you have to scale this.FabricCanvas.contextContainer that gets created and referenced on fabric.Canvas initialization.
I suggest you to switch to newer fabric anyway.
I want to split up a document by quotation it's marks. I see (here) that they're able to fake this answer by adding a '\' at the beginning of the quotation mark, however in my document there are hundreds of these strings I'm trying to cut string out of, so changing that manually would be a real pain and time taker.
Here's an example of the string I'm trying to cut from:
D
And here's an example of my current code:
private function onShopTextLoaded(e:Event):void
{
shopArrayOfWebsites = e.target.data.split(/\n/);
for (var i:String in shopArrayOfWebsites)
{
trace("shopArrayOriginal: " + shopArrayOfWebsites[i]);
var arrayString:String = shopArrayOfWebsites[i].split('"' /* << that won't work */ );
trace(arrayString[1]);
//shopArrayOfWebsites[i] = arrayString[1];
}
}
private function postInShopView():void
{
var iLevel:Number = 1;
var iSection:Number = 1;
var iShop:Number = 0;
for (var i:String in shopArrayOfWebsites)
{
iShop++;
if(iShop >= 5)
{
iSection++;
iShop = 0;
}
if(iSection >= 5)
{
iLevel++;
iSection = 1;
}
var shopStringEquiv:String = "L" + iLevel.toString() + "S" + iSection.toString() + "Shop" + iShop.toString();
if(global.shopTarget == shopStringEquiv)
{
var result:uint = ExternalInterface.call("showShopFrame", shopArrayOfWebsites[i]);
}
//trace(shopStringEquiv);
//trace(shopArrayOfWebsites[i]);
}
}
I get an error of:
ReferenceError: Error #1069: Property 1 not found on String and there is no default value.
So from here I'm not quite sure how I'm able to split up this document. Any ideas? Thanks!
I had this problem on my three sharepoint sites and i manage to resolve this problem by modifying CSS code (cf http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/64796605-bcbb-4a87-9d8d-9d609579577f/) on two of them.
I don't know why this doesn't work on my third one which has same updates, same CSS and same html code...
I tried several solutions such as adding indesign="true"(this can't be use because the lists got more than 75 columns). cf
http://www.codeproject.com/Articles/194254/Advanced-fixing-SharePoint-2010-large-lookup-dropd
The only solutions i found required javascript but i don't really want to use it...
If someone have another solution to propose, i would really appreciate.
EDIT:
Thanks to moontear i found something quite great.
I replace the beginning of the script by :
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
...
By this way, i just have to include the script and don't care about what columns got problems...
This script seems to be quite great to solve this problem...
Thank you moontear for your comment
The original script come from : http://sharepointegg.blogspot.de/2010/10/fixing-sharepoint-2010-lookup-drop-down.html
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
// Construct a drop down list object
var lookupDDL = new DropDownList(columnName);
// Do this only in complex mode...
if (lookupDDL.Type == "C") {
// Hide the text box and drop down arrow
lookupDDL.Obj.css('display', 'none');
lookupDDL.Obj.next("img").css('display', 'none');
// Construct the simple drop down field with change trigger
var tempDDLName = "tempDDLName_" + columnName;
if (lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").length == 0) {
lookupDDL.Obj.parent().append("<select name='" + tempDDLName + "' id='" + tempDDLName + "' title='" + tempDDLName + "'></select>");
lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").bind("change", function () {
updateOriginalField(columnName, tempDDLName);
});
}
// Get all the options
var splittedChoices = lookupDDL.Obj.attr('choices').split("|");
// get selected value
var hiddenVal = $('input[name=' + lookupDDL.Obj.attr("optHid") + ']').val();
if (hiddenVal == "0") {
hiddenVal = lookupDDL.Obj.attr("value")
}
// Replacing the drop down object with the simple drop down list
lookupDDL = new DropDownList(tempDDLName);
// Populate the drop down list
for (var i = 0; i < splittedChoices.length; i++) {
var optionVal = splittedChoices[i];
i++;
var optionId = splittedChoices[i];
var selected = (optionId == hiddenVal) ? " selected='selected'" : "";
lookupDDL.Obj.append("<option" + selected + " value='" + optionId + "'>" + optionVal + "</option>");
}
}
}
// method to update the original and hidden field.
function updateOriginalField(child, temp) {
var childSelect = new DropDownList(child);
var tempSelect = new DropDownList(temp);
// Set the text box
childSelect.Obj.attr("value", tempSelect.Obj.find("option:selected").val());
// Get Hidden ID
var hiddenId = childSelect.Obj.attr("optHid");
// Update the hidden variable
$('input[name=' + hiddenId + ']').val(tempSelect.Obj.find("option:selected").val());
}
// just to construct a drop down box object. Idea token from SPServces
function DropDownList(colName) {
// Simple - when they are less than 20 items
if ((this.Obj = $("select[Title='" + colName + "']")).html() != null) {
this.Type = "S";
// Compound - when they are more than 20 items
} else if ((this.Obj = $("input[Title='" + colName + "']")).html() != null) {
this.Type = "C";
// Multi-select: This will find the multi-select column control on English and most other languages sites where the Title looks like 'Column Name possible values'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title^='" + colName + " ']")).html() != null) {
this.Type = "M";
// Multi-select: This will find the multi-select column control on a Russian site (and perhaps others) where the Title looks like '????????? ????????: Column Name'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title$=': " + colName + "']")).html() != null) {
this.Type = "M";
} else
this.Type = null;
} // End of function dropdownCtl
});
The code in the solution above is great, but it has two major shortcomings:
1) Doesn't play nicely with Required Field Validators
2) Doesn't play nicely with Cascading Dropdowns via SPServices.
I've fixed these two problems at work, and put my solution here:
http://craigvsthemachine.blogspot.com/2013/04/fixing-complex-dropdown-bug-in.html
Given the following example SWF:
Sample
Notice how with the words "enthusiast" at the end of the first line and "write" at the end of the second line, that they start to type out on the first line but after a few letters they are bumped.
I understand this is the correct behavior, but is there a way for "enthusiast" to begin being typed on the second line, and "write" on the third line instead of being bumped during the typing?
Currently I am thinking of doing a search ahead mechanism, so it finds the next word in whole, then makes that the active word to print, temporarily print it, see if it increases the numlines, and if it does insert a line break and continue writing. But it seems fiddly.
Code below:
import flash.text.TextField;
import flash.events.Event;
var tt:TextField = new TextField();
tt.wordWrap = true;
tt.width = 200;
tt.height = 50;
tt.border = true;
var s = "Stack Overflow is for professional and enthusiast programmers, people who write code because they love it. We feel the best Stack Overflow questions have a bit of source code in them, but if your question generally covers";
addChild(tt);
var currentLetter:int = 0;
addEventListener(Event.ENTER_FRAME, onEnter, false, 0, true);
function onEnter(e:Event):void
{
if(currentLetter < s.length)
{
tt.appendText(s.charAt(currentLetter));
}
currentLetter++;
}
adjusted your code a bit and posted the result on wonderfl: http://wonderfl.net/c/rZkm
as #mouseas suggested i put the next word into an additional textfield measure the width and compare this to the remaining space in the current line ... if the next word doesn't fit I add a line-break and continue.
here's the code:
package {
import flash.geom.Rectangle;
import flash.text.TextFieldAutoSize;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
public class FlashTest extends Sprite {
private var currentLetter:int = 0;
private var tt:TextField;
private var debug:TextField;
private var pre:TextField;
private var s:String;
public function FlashTest()
{
// write as3 code here..
tt = new TextField();
tt.wordWrap = true;
tt.width = 200;
tt.height = 150;
tt.border = true;
s = "Stack Overflow is for professional and enthusiast programmers, people who write code because they love it. We feel the best Stack Overflow questions have a bit of source code in them, but if your question generally covers";
addChild(tt);
// predraw word
pre = new TextField();
pre.y = 150;
pre.width = 200;
pre.height = 50;
pre.autoSize = TextFieldAutoSize.LEFT;
pre.border = true;
addChild(pre);
// debug txt
debug = new TextField();
debug.x = 250;
debug.wordWrap = true;
debug.width = 200;
debug.height = 500;
debug.border = true;
addChild(debug);
addEventListener(Event.ENTER_FRAME, onEnter, false, 0, true);
}
private function onEnter(e:Event):void
{
//debug.appendText("char: " + rect.x + " " + rect.width + "\n");
var c:String = "";
if (currentLetter < s.length)
{
c = s.charAt(currentLetter);
tt.appendText(c);
}
else
{
debug.appendText("DONE! \n");
removeEventListener(Event.ENTER_FRAME, onEnter);
}
if (c == " ")
{
var rect:Rectangle = tt.getCharBoundaries(currentLetter-1);
if (rect != null)
{
//debug.appendText("char: " + rect + "\n");
var cPos:int = rect.x + rect.width;
var r:int = tt.width - 4 - cPos; // 4px for gutter on left+right side of textfield
var start:int = s.lastIndexOf(" ", currentLetter);
var end:int = s.indexOf(" ", currentLetter+1);
if (start < 0) start = 0;
pre.text = s.substr(start, end-start);
debug.appendText("rest: " + r + " " + pre.textWidth + " > " + pre.text + "\n");
if (r - pre.textWidth <= 0)
{
tt.appendText("\n");
debug.appendText("\n");
}
//debug.appendText("w:" + tt.textWidth + " " + start + "->"+ end + " /" + pre.text + "/ " + pre.textWidth + "\n");
}
}
++currentLetter;
}
}
}
works great - only the "a" in the 4th line makes trouble - maybe you need to finetune the calculations a bit...
I am using YUI and need to get the true width of the element. The width of an element can be determined as follows.
width + border-left + border-right + padding-left + padding-right + margin-left + margin-right.
Below is what I have come up with. It appears to be working. I was just wondering if this is the best way to go about determining this or is there there a more efficient way?
YUI().use('node', function(Y) {
var node = Y.one('#nav');
var nodeWidth = trueElementWidth(node);
alert(nodeWidth);
});
function trueElementWidth(el) {
var width = 0;
var attributes = ['border-left', 'border-right', 'padding-left', 'padding-right', 'width', 'margin-right', 'margin-left'];
for(var i=0; i < attributes.length; i++) {
width = width + removePx(el.getComputedStyle(attributes[i]));
}
return width;
}
function removePx(el) {
el = el.toString();
length = el.length - 2;
elDimension = parseInt(el.substring(0, length));
return isNaN(elDimension) ? 0 : elDimension;
}
There is an offsetWidth property that returns exactly what you want.