youtube / spfjs

A lightweight JS framework for fast navigation and page updates from YouTube
https://youtube.github.io/spfjs/
MIT License
2.24k stars 147 forks source link

SPF.js doesn't return responses when we have multiple lines! #438

Open kamrava opened 7 years ago

kamrava commented 7 years ago

SPF.js doesn't work with this:

<link rel=\"stylesheet\" href=\"css/style1.css\">
<link rel=\"stylesheet\" href=\"css/style2.css\">
<link rel=\"stylesheet\" href=\"css/style3.css\">

But if I put all lines into one line it works fine. Like this: <link rel=\"stylesheet\" href=\"css/style1.css\"><link rel=\"stylesheet\" href=\"css/style2.css\"><link rel=\"stylesheet\" href=\"css/style3.css\">

Why SPF.js doesn't work in multiple lines?

rviscomi commented 7 years ago

White space doesn't affect the DOM, so I doubt that's what's causing your issue. Can you post a jsfiddle with an example of your code not working?

kamrava commented 7 years ago

I'm trying to integrating SPF.js with Laravel. Here is my structure:

views/users-list/head.blade.php views/users-list/body.blade.php views/users-list/foot.blade.php views/users-list/index.blade.php

head.blade.php

<link rel="stylesheet" href="css/style1.css">
<link rel="stylesheet" href="css/style2.css">
<link rel="stylesheet" href="css/style3.css">

body.blade.php

<div class="row">
  <div class="col-md-12">
    <table id="UsersTable" class="table">
      <thead>
      <tr>
          <th>ID</th>
          <th>Last Name</th>
          <th>Email</th>
          <th>Mobile</th>
      </tr>
      </thead>
      <tbody>
       <tr>
          <td>1</td>
          <td>Alex</td>
          <td>alex@gmail.com</td>
          <td>123456</td>
       </tr>
       <tr>
          <td>2</td>
          <td>David</td>
          <td>david@gmail.com</td>
          <td>9454654</td>
       </tr>
      </tbody>
  </table>
  </div>
</div>

foot.blade.php

<script src="/js/bootbox.min.js"></script>
<script src="/js/datatables.min.js"></script>
<script src="/js/datatables.bootstrap.js"></script>

index.blade.php

{
  "head": "@include('users-list.head')",
  "body": {
    "spf-posts-container": "@include('users-list.body')"
  },
  "foot": "@include('users-list.foot')"
}

As you can see everything is solid and clear in my structure but this is not working until I manually replace all " with \" and also put all lines into one line in each blade file(head.blade.php, body.blade.php, foot.blade.php)

Like so:

head.blade.php

@php
$head = <<< EOT
<link rel="stylesheet" href="css/style1.css">
<link rel="stylesheet" href="css/style2.css">
<link rel="stylesheet" href="css/style3.css">
EOT;

$head = str_replace(array("\r","\n"),"", $head);
echo str_replace("\"","\\\"", $head);
@endphp

body.blade.php

@php
$body = <<< EOT
<div class="row">
  <div class="col-md-12">
    <table id="UsersTable" class="table">
      <thead>
      <tr>
          <th>ID</th>
          <th>Last Name</th>
          <th>Email</th>
          <th>Mobile</th>
      </tr>
      </thead>
      <tbody>
       <tr>
          <td>1</td>
          <td>Alex</td>
          <td>alex@gmail.com</td>
          <td>123456</td>
       </tr>
       <tr>
          <td>2</td>
          <td>David</td>
          <td>david@gmail.com</td>
          <td>9454654</td>
       </tr>
      </tbody>
  </table>
  </div>
</div>
EOT;

$body = str_replace(array("\r","\n"),"", $body);
echo str_replace("\"","\\\"", $body);
@endphp

foot.blade.php

@php
$foot = <<< EOT
<script src="/js/bootbox.min.js"></script>
<script src="/js/datatables.min.js"></script>
<script src="/js/datatables.bootstrap.js"></script>
EOT;

$foot = str_replace(array("\r","\n"),"", $foot);
echo str_replace("\"","\\\"", $foot);
@endphp

It works but I don't like it! it makes my code messy ...

Any ideas?

PhilHarnish commented 7 years ago

I think the issue is in "index.blade.php". These lines:

{
  "head": "@include('users-list.head')",
  "body": {
    "spf-posts-container": "@include('users-list.body')"
  },
  "foot": "@include('users-list.foot')"
}

are instructing PHP to inject the contents of the other files, in line. So if "users-list/head.php" contained this string: end of head", "new_attribute": "new_value you would end up with this output:

{
  "head": "end of head", "new_attribute": "new_value",
  ...

Which of course is not what you intended. See if you can find a method in PHP for escaping string values for use in JSON. Perhaps this? http://php.net/manual/en/function.addslashes.php

kamrava commented 7 years ago

You are right about slashes. But I can't understand why it only works when I put all lines into one line! If I don't it won't work! Any ideas?

PhilHarnish commented 7 years ago

Yes, same issue.

If "users-list/head.php" contained this:

line 1
line 2
line 3

You would end up with this output:

{
  "head": "line break 1: 
line break 2: 
line 3",
  "body": {
  ...

Which is also invalid JSON (see "string" section of JSON definition). If you're able to find a method to load a file in PHP and escape use the "addslashes" method it will also convert newline characters to something acceptable for a JSON string (which is the 2-character string "\n").

kamrava commented 7 years ago

Thank You, I've provided a Laravel Package. laravel-spfjs :)