anseki / plain-draggable

The simple and high performance library to allow HTML/SVG element to be dragged.
https://anseki.github.io/plain-draggable/
MIT License
765 stars 96 forks source link

How to use WordPress (Issue being unrelated to PlainDraggable) #23

Closed LetsHaveASquint closed 5 years ago

LetsHaveASquint commented 5 years ago

Hi! So I’ve made a little game that works as planned as a normal web page (see the CodePen here: https://codepen.io/squinter/pen/VNMpgW).

But, when I put it into a local server WordPress page I get this error and nothing works: TypeError: undefined is not an object (evaluating 'p0.cx.baseVal')

The error references line 55 in the JS part of the Pen. I’m stumped.

FYI is that I’m using the WP Scripts n Styles plug-in on the WP site. I’ve done other pages there using plain draggable and those seem to work well.

While I can pull the game in via an iFrame (which does work), I’d prefer not to.

anseki commented 5 years ago

Hi @LetsHaveASquint, thank you for your comment.

So, you have to reproduce a matter to inspect any problem. And also, I have to see that error to help you. Can you reproduce that? For example, copy the source codes from the shown web page via your local server to the CodePen or another after you confirm that the error was thrown.

anseki commented 5 years ago

@LetsHaveASquint wrote:

Hi, I made a password protected page on a site I manage. See the page here https://atelierrousar.com/pd-tests .

The password is: drag-plain1

Just like in the CodePen (https://codepen.io/squinter/pen/VNMpgW), when the page loads:

  1. A red, randomly generated svg line should appear.
  2. A plain draggable svg path should appear.

Line 543 of the rendered page throws the error (TypeError: undefined is not an object (evaluating 'p0.cx.baseVal').

I copied the source code from the shown web page to JSFiddle on your behalf. Why you never do that? As I said, you have to reproduce a matter to inspect any problem. And also, I have to see that error to help you. And also, this is the first step of the best solution.

Anyway, I copied the source code to JSFiddle on your behalf. And very easy mistake was found very easily. https://jsfiddle.net/yjnp8c7w/ Maybe, you wrote SVG code in text-box for comment of a post, not Scripts n Styles. Then the SVG document is broken. (incorrect <br /> tags are included.) Then, the p0 and others do not have SVG elements (i.e. p0 does not have cx). Try to remove <br /> tags and click "Run" button.

Also, you should notice that the error was thrown before PlainDraggable is called, and the above JSFiddle page does not load PlainDraggable.

I again encourage you to do that. You should reproduce a matter to inspect any problem. Also, this is the first step of the best solution. And it is fastest way to solve. If you did that, you should have found the mistake in 5 minutes.

LetsHaveASquint commented 5 years ago

Hi! Thank you!

As you know I am trying to learn on my own. As such, there are a lot of things I miss (like the importance of JSFiddle). I thought that JSFiddle and CodePen were simply competitors doing the same thing. Therefore I thought I was reproducing the problem (using CodePen), but I clearly was not. Had I separated out the offending code as you did, but using CodePen, I might have seen the problem too. Anyway, I'll study JSFiddle a little more from now on.

Regarding the problem. . . It must be something WordPress is adding (I did not add the
tags). But I will look into that.

Thanks once again for all your time and direction. I appreciate it.

anseki commented 5 years ago

I am learning too, let's do our best. :smile: Of course you can use CodePen (or another Online Code Playground Service) instead of JSFiddle. An important point is that the your code in CodePen did not reproduce the problem. As I suggested, if you tried to copy the source codes to the CodePen, you should have found the cause of the problem. Because you have to select parts for reproducing that, and you find the strange code (broken SVG). It is not important whether it is JSFiddle or not. That is, work to reproduce the problem is work to narrow down parts that are required for the problem.

BTW, WordPress text editor inserts br tags, and the "Scripts n Styles" is a plugin to avoid inserting the tags. You can add any codes without br tags via the plugin, not only JavaScript. For example, you can add SVG code:

</script>
<!-- Write your SVG code here. -->
<svg>
</svg>
<!-- And others if you want. -->
<script>

See document of Scripts n Styles.

anseki commented 5 years ago

ADDITION:

Generally speaking, you had better add a script, HTML and others to a post via <iframe> element because it makes those components work safely and certainly. The <iframe> element can separate a name space and style definitions from parent page.

As you know, WordPress is a blogging software. It can show posts that the user wants (e.g. newest as default, searching something, specific month, specific tags, etc.). Then, the post that contains script and components might be shown with another post that contains something in same page. For example, another element that has id="rndLine" makes your script fail, svg { background-color: red; } dirties your components, etc.

And also, <iframe> element solves the problem about the <br> tags.

Popular web components (e.g. Facebook Like button, YouTube movie, Twitter Tweet button, etc.) are added via <iframe> element safely.

LetsHaveASquint commented 5 years ago

Hi, Good point(s). An iframe did work for me, sort of. But it became too difficult to make the iframed content responsive. It would not scale correctly relative to its container.

That might be something that can be solved though, and therefore would not risk the concerns you mention. I'll look into it now.

Thanks again!

LetsHaveASquint commented 5 years ago

I also looked into a Vue app and creating a Web Component (shadowDOM, etc.) but then I quickly got lost. :)

anseki commented 5 years ago

The style for scale of the <iframe> is easy. Try this:

<div id="wrapper">
  <iframe src="foo.html"></iframe>
</div>
#wrapper {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* height / width * 100 */
}

#wrapper iframe {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
LetsHaveASquint commented 5 years ago

Thanks. That works for the SVG elements but it cuts off the buttons on browser resize. I was able to use a template (document fragment) in the JavaScript code, appending that child to a div with an id of 'svg-outer': let tpl = document.createElement('template'); tpl.innerHTML = '-all the html code goes here-'; document.getElementById('svg-outer').appendChild(tpl.content);

On resize this seems to work well in Safari. I'll test other browsers as well.

anseki commented 5 years ago

You can use calc() function to add a static value (size of buttons) to the flexible value (size of SVG). For example, add 32px for buttons to the height:

padding-top: calc(40% + 32px);

Also, you can use "media queries" to adjust the layout for small viewport. For example, change style of buttons for small viewport.

@media screen and (max-width: 383px) {
  #wrapper {
    padding-top: calc(40% + 96px);
  }
}

See: https://jsfiddle.net/yseko724/ Drag a vertical border line at the center to resize the bottom-right view. The buttons are arranged vertically when you make the view be small.

anseki commented 5 years ago

BTW, why did you use the template? Did you use that instead of <iframe>? Or, did you use that to avoid <br> tags? I mean, I can't understand how the template has any relations with current issue.

LetsHaveASquint commented 5 years ago

Hi! Thanks. I did use media queries (without calc), but I'll try the calc option.

Why did I use the template?

It was a very long road (and day) to solve the following issues:

So, every way I tried with my current level of knowledge had problems! All due to one or another aspect of how WP allows me to put the content into a page. I guessed that there must be a way to do it mostly using JavaScript and I found documentFragment/template/appendChild as a solution. It's the only thing I could get to work as intended (so far).

I'm happy with it, even though I risk id and class name contamination from future plugins or even WP itself.

It's still odd though that other 'games' work fine when added to the page in a simple way (divs in the page text editor and scripts/css added through Scripts n Styles). When I made this one I surely did something that caused all this! I try to run before I can walk I guess. :)

I'd have put all those failed attempts into a Fiddle but since we now know that none of it involves Plain Draggable I did not want to keep involving you and wasting your time.

anseki commented 5 years ago

I see. Maybe I don't know your situation perfectly, but I think that the way using <iframe> without Scripts n Styles is best solution. Also, if you master this technique, it should help you in future. I hope that the latest JSFiddle page using <iframe> helps you.

LetsHaveASquint commented 5 years ago

Good advice Anseki. Yes, that was a big help! Thanks.

LetsHaveASquint commented 5 years ago

Just to close this off. I used the iFrame with the calc info you suggested. It worked perfectly! Thank you once again.

anseki commented 5 years ago

:smile:

anseki commented 5 years ago

Sorry, I don't know why, but the data of this issue was broken. I tried repair that: https://github.com/anseki/plain-draggable/issues/23#issuecomment-483496639